1 2 /* 3 This is where the abstract matrix operations are defined 4 */ 5 6 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 7 #include <petsc/private/isimpl.h> 8 #include <petsc/private/vecimpl.h> 9 10 /* Logging support */ 11 PetscClassId MAT_CLASSID; 12 PetscClassId MAT_COLORING_CLASSID; 13 PetscClassId MAT_FDCOLORING_CLASSID; 14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 15 16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 36 PetscLogEvent MAT_ViennaCLCopyToGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 39 40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 41 42 /*@ 43 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations 44 45 Logically Collective on Mat 46 47 Input Parameters: 48 + x - the matrix 49 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 50 it will create one internally. 51 52 Output Parameter: 53 . x - the matrix 54 55 Example of Usage: 56 .vb 57 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 58 MatSetRandom(x,rctx); 59 PetscRandomDestroy(rctx); 60 .ve 61 62 Level: intermediate 63 64 Concepts: matrix^setting to random 65 Concepts: random^matrix 66 67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 68 @*/ 69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 70 { 71 PetscErrorCode ierr; 72 PetscRandom randObj = NULL; 73 74 PetscFunctionBegin; 75 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 76 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 77 PetscValidType(x,1); 78 79 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 80 81 if (!rctx) { 82 MPI_Comm comm; 83 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 84 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 85 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 86 rctx = randObj; 87 } 88 89 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 91 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 92 93 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 94 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 95 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 101 102 Logically Collective on Mat 103 104 Input Parameters: 105 . mat - the factored matrix 106 107 Output Parameter: 108 + pivot - the pivot value computed 109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 110 the share the matrix 111 112 Level: advanced 113 114 Notes: 115 This routine does not work for factorizations done with external packages. 116 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 117 118 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 119 120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 121 @*/ 122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 123 { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 126 *pivot = mat->factorerror_zeropivot_value; 127 *row = mat->factorerror_zeropivot_row; 128 PetscFunctionReturn(0); 129 } 130 131 /*@ 132 MatFactorGetError - gets the error code from a factorization 133 134 Logically Collective on Mat 135 136 Input Parameters: 137 . mat - the factored matrix 138 139 Output Parameter: 140 . err - the error code 141 142 Level: advanced 143 144 Notes: 145 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 146 147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 148 @*/ 149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 150 { 151 PetscFunctionBegin; 152 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 153 *err = mat->factorerrortype; 154 PetscFunctionReturn(0); 155 } 156 157 /*@ 158 MatFactorClearError - clears the error code in a factorization 159 160 Logically Collective on Mat 161 162 Input Parameter: 163 . mat - the factored matrix 164 165 Level: developer 166 167 Notes: 168 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 169 170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 171 @*/ 172 PetscErrorCode MatFactorClearError(Mat mat) 173 { 174 PetscFunctionBegin; 175 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 176 mat->factorerrortype = MAT_FACTOR_NOERROR; 177 mat->factorerror_zeropivot_value = 0.0; 178 mat->factorerror_zeropivot_row = 0; 179 PetscFunctionReturn(0); 180 } 181 182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 183 { 184 PetscErrorCode ierr; 185 Vec r,l; 186 const PetscScalar *al; 187 PetscInt i,nz,gnz,N,n; 188 189 PetscFunctionBegin; 190 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 191 if (!cols) { /* nonzero rows */ 192 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 193 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 194 ierr = VecSet(l,0.0);CHKERRQ(ierr); 195 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 196 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 197 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 198 } else { /* nonzero columns */ 199 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 200 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 201 ierr = VecSet(r,0.0);CHKERRQ(ierr); 202 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 203 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 204 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 205 } 206 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 207 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 208 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 209 if (gnz != N) { 210 PetscInt *nzr; 211 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 212 if (nz) { 213 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 215 } 216 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 217 } else *nonzero = NULL; 218 if (!cols) { /* nonzero rows */ 219 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 220 } else { 221 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 222 } 223 ierr = VecDestroy(&l);CHKERRQ(ierr); 224 ierr = VecDestroy(&r);CHKERRQ(ierr); 225 PetscFunctionReturn(0); 226 } 227 228 /*@ 229 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 230 231 Input Parameter: 232 . A - the matrix 233 234 Output Parameter: 235 . keptrows - the rows that are not completely zero 236 237 Notes: 238 keptrows is set to NULL if all rows are nonzero. 239 240 Level: intermediate 241 242 @*/ 243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 244 { 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 249 PetscValidType(mat,1); 250 PetscValidPointer(keptrows,2); 251 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 252 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 253 if (!mat->ops->findnonzerorows) { 254 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 255 } else { 256 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 257 } 258 PetscFunctionReturn(0); 259 } 260 261 /*@ 262 MatFindZeroRows - Locate all rows that are completely zero in the matrix 263 264 Input Parameter: 265 . A - the matrix 266 267 Output Parameter: 268 . zerorows - the rows that are completely zero 269 270 Notes: 271 zerorows is set to NULL if no rows are zero. 272 273 Level: intermediate 274 275 @*/ 276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 277 { 278 PetscErrorCode ierr; 279 IS keptrows; 280 PetscInt m, n; 281 282 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 283 PetscValidType(mat,1); 284 285 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 286 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 287 In keeping with this convention, we set zerorows to NULL if there are no zero 288 rows. */ 289 if (keptrows == NULL) { 290 *zerorows = NULL; 291 } else { 292 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 293 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 294 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 295 } 296 PetscFunctionReturn(0); 297 } 298 299 /*@ 300 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 301 302 Not Collective 303 304 Input Parameters: 305 . A - the matrix 306 307 Output Parameters: 308 . a - the diagonal part (which is a SEQUENTIAL matrix) 309 310 Notes: 311 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 312 Use caution, as the reference count on the returned matrix is not incremented and it is used as 313 part of the containing MPI Mat's normal operation. 314 315 Level: advanced 316 317 @*/ 318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 319 { 320 PetscErrorCode ierr; 321 322 PetscFunctionBegin; 323 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 324 PetscValidType(A,1); 325 PetscValidPointer(a,3); 326 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 327 if (!A->ops->getdiagonalblock) { 328 PetscMPIInt size; 329 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 330 if (size == 1) { 331 *a = A; 332 PetscFunctionReturn(0); 333 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 334 } 335 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 336 PetscFunctionReturn(0); 337 } 338 339 /*@ 340 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 341 342 Collective on Mat 343 344 Input Parameters: 345 . mat - the matrix 346 347 Output Parameter: 348 . trace - the sum of the diagonal entries 349 350 Level: advanced 351 352 @*/ 353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 354 { 355 PetscErrorCode ierr; 356 Vec diag; 357 358 PetscFunctionBegin; 359 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 360 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 361 ierr = VecSum(diag,trace);CHKERRQ(ierr); 362 ierr = VecDestroy(&diag);CHKERRQ(ierr); 363 PetscFunctionReturn(0); 364 } 365 366 /*@ 367 MatRealPart - Zeros out the imaginary part of the matrix 368 369 Logically Collective on Mat 370 371 Input Parameters: 372 . mat - the matrix 373 374 Level: advanced 375 376 377 .seealso: MatImaginaryPart() 378 @*/ 379 PetscErrorCode MatRealPart(Mat mat) 380 { 381 PetscErrorCode ierr; 382 383 PetscFunctionBegin; 384 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 385 PetscValidType(mat,1); 386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 388 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 389 MatCheckPreallocated(mat,1); 390 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 392 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 393 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 394 } 395 #endif 396 PetscFunctionReturn(0); 397 } 398 399 /*@C 400 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 401 402 Collective on Mat 403 404 Input Parameter: 405 . mat - the matrix 406 407 Output Parameters: 408 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 409 - ghosts - the global indices of the ghost points 410 411 Notes: 412 the nghosts and ghosts are suitable to pass into VecCreateGhost() 413 414 Level: advanced 415 416 @*/ 417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 418 { 419 PetscErrorCode ierr; 420 421 PetscFunctionBegin; 422 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 423 PetscValidType(mat,1); 424 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 425 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 426 if (!mat->ops->getghosts) { 427 if (nghosts) *nghosts = 0; 428 if (ghosts) *ghosts = 0; 429 } else { 430 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 431 } 432 PetscFunctionReturn(0); 433 } 434 435 436 /*@ 437 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 438 439 Logically Collective on Mat 440 441 Input Parameters: 442 . mat - the matrix 443 444 Level: advanced 445 446 447 .seealso: MatRealPart() 448 @*/ 449 PetscErrorCode MatImaginaryPart(Mat mat) 450 { 451 PetscErrorCode ierr; 452 453 PetscFunctionBegin; 454 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 455 PetscValidType(mat,1); 456 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 457 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 458 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 459 MatCheckPreallocated(mat,1); 460 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 462 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 463 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 464 } 465 #endif 466 PetscFunctionReturn(0); 467 } 468 469 /*@ 470 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 471 472 Not Collective 473 474 Input Parameter: 475 . mat - the matrix 476 477 Output Parameters: 478 + missing - is any diagonal missing 479 - dd - first diagonal entry that is missing (optional) on this process 480 481 Level: advanced 482 483 484 .seealso: MatRealPart() 485 @*/ 486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 487 { 488 PetscErrorCode ierr; 489 490 PetscFunctionBegin; 491 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 492 PetscValidType(mat,1); 493 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 494 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 495 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 496 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 497 PetscFunctionReturn(0); 498 } 499 500 /*@C 501 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 502 for each row that you get to ensure that your application does 503 not bleed memory. 504 505 Not Collective 506 507 Input Parameters: 508 + mat - the matrix 509 - row - the row to get 510 511 Output Parameters: 512 + ncols - if not NULL, the number of nonzeros in the row 513 . cols - if not NULL, the column numbers 514 - vals - if not NULL, the values 515 516 Notes: 517 This routine is provided for people who need to have direct access 518 to the structure of a matrix. We hope that we provide enough 519 high-level matrix routines that few users will need it. 520 521 MatGetRow() always returns 0-based column indices, regardless of 522 whether the internal representation is 0-based (default) or 1-based. 523 524 For better efficiency, set cols and/or vals to NULL if you do 525 not wish to extract these quantities. 526 527 The user can only examine the values extracted with MatGetRow(); 528 the values cannot be altered. To change the matrix entries, one 529 must use MatSetValues(). 530 531 You can only have one call to MatGetRow() outstanding for a particular 532 matrix at a time, per processor. MatGetRow() can only obtain rows 533 associated with the given processor, it cannot get rows from the 534 other processors; for that we suggest using MatCreateSubMatrices(), then 535 MatGetRow() on the submatrix. The row index passed to MatGetRow() 536 is in the global number of rows. 537 538 Fortran Notes: 539 The calling sequence from Fortran is 540 .vb 541 MatGetRow(matrix,row,ncols,cols,values,ierr) 542 Mat matrix (input) 543 integer row (input) 544 integer ncols (output) 545 integer cols(maxcols) (output) 546 double precision (or double complex) values(maxcols) output 547 .ve 548 where maxcols >= maximum nonzeros in any row of the matrix. 549 550 551 Caution: 552 Do not try to change the contents of the output arrays (cols and vals). 553 In some cases, this may corrupt the matrix. 554 555 Level: advanced 556 557 Concepts: matrices^row access 558 559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 560 @*/ 561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 562 { 563 PetscErrorCode ierr; 564 PetscInt incols; 565 566 PetscFunctionBegin; 567 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 568 PetscValidType(mat,1); 569 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 570 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 571 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 572 MatCheckPreallocated(mat,1); 573 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 574 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 575 if (ncols) *ncols = incols; 576 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 577 PetscFunctionReturn(0); 578 } 579 580 /*@ 581 MatConjugate - replaces the matrix values with their complex conjugates 582 583 Logically Collective on Mat 584 585 Input Parameters: 586 . mat - the matrix 587 588 Level: advanced 589 590 .seealso: VecConjugate() 591 @*/ 592 PetscErrorCode MatConjugate(Mat mat) 593 { 594 #if defined(PETSC_USE_COMPLEX) 595 PetscErrorCode ierr; 596 597 PetscFunctionBegin; 598 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 599 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 600 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"); 601 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 603 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 604 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 605 } 606 #endif 607 PetscFunctionReturn(0); 608 #else 609 return 0; 610 #endif 611 } 612 613 /*@C 614 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 615 616 Not Collective 617 618 Input Parameters: 619 + mat - the matrix 620 . row - the row to get 621 . ncols, cols - the number of nonzeros and their columns 622 - vals - if nonzero the column values 623 624 Notes: 625 This routine should be called after you have finished examining the entries. 626 627 This routine zeros out ncols, cols, and vals. This is to prevent accidental 628 us of the array after it has been restored. If you pass NULL, it will 629 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 630 631 Fortran Notes: 632 The calling sequence from Fortran is 633 .vb 634 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 635 Mat matrix (input) 636 integer row (input) 637 integer ncols (output) 638 integer cols(maxcols) (output) 639 double precision (or double complex) values(maxcols) output 640 .ve 641 Where maxcols >= maximum nonzeros in any row of the matrix. 642 643 In Fortran MatRestoreRow() MUST be called after MatGetRow() 644 before another call to MatGetRow() can be made. 645 646 Level: advanced 647 648 .seealso: MatGetRow() 649 @*/ 650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 651 { 652 PetscErrorCode ierr; 653 654 PetscFunctionBegin; 655 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 656 if (ncols) PetscValidIntPointer(ncols,3); 657 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 658 if (!mat->ops->restorerow) PetscFunctionReturn(0); 659 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 660 if (ncols) *ncols = 0; 661 if (cols) *cols = NULL; 662 if (vals) *vals = NULL; 663 PetscFunctionReturn(0); 664 } 665 666 /*@ 667 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 668 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 669 670 Not Collective 671 672 Input Parameters: 673 + mat - the matrix 674 675 Notes: 676 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. 677 678 Level: advanced 679 680 Concepts: matrices^row access 681 682 .seealso: MatRestoreRowRowUpperTriangular() 683 @*/ 684 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 685 { 686 PetscErrorCode ierr; 687 688 PetscFunctionBegin; 689 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 690 PetscValidType(mat,1); 691 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 692 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 693 if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 694 MatCheckPreallocated(mat,1); 695 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 696 PetscFunctionReturn(0); 697 } 698 699 /*@ 700 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 701 702 Not Collective 703 704 Input Parameters: 705 + mat - the matrix 706 707 Notes: 708 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 709 710 711 Level: advanced 712 713 .seealso: MatGetRowUpperTriangular() 714 @*/ 715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 716 { 717 PetscErrorCode ierr; 718 719 PetscFunctionBegin; 720 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 721 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 722 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 723 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 724 PetscFunctionReturn(0); 725 } 726 727 /*@C 728 MatSetOptionsPrefix - Sets the prefix used for searching for all 729 Mat options in the database. 730 731 Logically Collective on Mat 732 733 Input Parameter: 734 + A - the Mat context 735 - prefix - the prefix to prepend to all option names 736 737 Notes: 738 A hyphen (-) must NOT be given at the beginning of the prefix name. 739 The first character of all runtime options is AUTOMATICALLY the hyphen. 740 741 Level: advanced 742 743 .keywords: Mat, set, options, prefix, database 744 745 .seealso: MatSetFromOptions() 746 @*/ 747 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 748 { 749 PetscErrorCode ierr; 750 751 PetscFunctionBegin; 752 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 753 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 754 PetscFunctionReturn(0); 755 } 756 757 /*@C 758 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 759 Mat options in the database. 760 761 Logically Collective on Mat 762 763 Input Parameters: 764 + A - the Mat context 765 - prefix - the prefix to prepend to all option names 766 767 Notes: 768 A hyphen (-) must NOT be given at the beginning of the prefix name. 769 The first character of all runtime options is AUTOMATICALLY the hyphen. 770 771 Level: advanced 772 773 .keywords: Mat, append, options, prefix, database 774 775 .seealso: MatGetOptionsPrefix() 776 @*/ 777 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 778 { 779 PetscErrorCode ierr; 780 781 PetscFunctionBegin; 782 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 783 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 784 PetscFunctionReturn(0); 785 } 786 787 /*@C 788 MatGetOptionsPrefix - Sets the prefix used for searching for all 789 Mat options in the database. 790 791 Not Collective 792 793 Input Parameter: 794 . A - the Mat context 795 796 Output Parameter: 797 . prefix - pointer to the prefix string used 798 799 Notes: 800 On the fortran side, the user should pass in a string 'prefix' of 801 sufficient length to hold the prefix. 802 803 Level: advanced 804 805 .keywords: Mat, get, options, prefix, database 806 807 .seealso: MatAppendOptionsPrefix() 808 @*/ 809 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 810 { 811 PetscErrorCode ierr; 812 813 PetscFunctionBegin; 814 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 815 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 816 PetscFunctionReturn(0); 817 } 818 819 /*@ 820 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 821 822 Collective on Mat 823 824 Input Parameters: 825 . A - the Mat context 826 827 Notes: 828 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 829 Currently support MPIAIJ and SEQAIJ. 830 831 Level: beginner 832 833 .keywords: Mat, ResetPreallocation 834 835 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 836 @*/ 837 PetscErrorCode MatResetPreallocation(Mat A) 838 { 839 PetscErrorCode ierr; 840 841 PetscFunctionBegin; 842 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 843 PetscValidType(A,1); 844 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 845 PetscFunctionReturn(0); 846 } 847 848 849 /*@ 850 MatSetUp - Sets up the internal matrix data structures for the later use. 851 852 Collective on Mat 853 854 Input Parameters: 855 . A - the Mat context 856 857 Notes: 858 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 859 860 If a suitable preallocation routine is used, this function does not need to be called. 861 862 See the Performance chapter of the PETSc users manual for how to preallocate matrices 863 864 Level: beginner 865 866 .keywords: Mat, setup 867 868 .seealso: MatCreate(), MatDestroy() 869 @*/ 870 PetscErrorCode MatSetUp(Mat A) 871 { 872 PetscMPIInt size; 873 PetscErrorCode ierr; 874 875 PetscFunctionBegin; 876 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 877 if (!((PetscObject)A)->type_name) { 878 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 879 if (size == 1) { 880 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 881 } else { 882 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 883 } 884 } 885 if (!A->preallocated && A->ops->setup) { 886 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 887 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 888 } 889 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 890 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 891 A->preallocated = PETSC_TRUE; 892 PetscFunctionReturn(0); 893 } 894 895 #if defined(PETSC_HAVE_SAWS) 896 #include <petscviewersaws.h> 897 #endif 898 /*@C 899 MatView - Visualizes a matrix object. 900 901 Collective on Mat 902 903 Input Parameters: 904 + mat - the matrix 905 - viewer - visualization context 906 907 Notes: 908 The available visualization contexts include 909 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 910 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 911 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 912 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 913 914 The user can open alternative visualization contexts with 915 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 916 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 917 specified file; corresponding input uses MatLoad() 918 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 919 an X window display 920 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 921 Currently only the sequential dense and AIJ 922 matrix types support the Socket viewer. 923 924 The user can call PetscViewerPushFormat() to specify the output 925 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 926 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 927 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 928 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 929 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 930 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 931 format common among all matrix types 932 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 933 format (which is in many cases the same as the default) 934 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 935 size and structure (not the matrix entries) 936 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 937 the matrix structure 938 939 Options Database Keys: 940 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 941 . -mat_view ::ascii_info_detail - Prints more detailed info 942 . -mat_view - Prints matrix in ASCII format 943 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 944 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 945 . -display <name> - Sets display name (default is host) 946 . -draw_pause <sec> - Sets number of seconds to pause after display 947 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 948 . -viewer_socket_machine <machine> - 949 . -viewer_socket_port <port> - 950 . -mat_view binary - save matrix to file in binary format 951 - -viewer_binary_filename <name> - 952 Level: beginner 953 954 Notes: 955 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 956 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 957 958 See the manual page for MatLoad() for the exact format of the binary file when the binary 959 viewer is used. 960 961 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 962 viewer is used. 963 964 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 965 and then use the following mouse functions. 966 + left mouse: zoom in 967 . middle mouse: zoom out 968 - right mouse: continue with the simulation 969 970 Concepts: matrices^viewing 971 Concepts: matrices^plotting 972 Concepts: matrices^printing 973 974 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 975 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 976 @*/ 977 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 978 { 979 PetscErrorCode ierr; 980 PetscInt rows,cols,rbs,cbs; 981 PetscBool iascii,ibinary; 982 PetscViewerFormat format; 983 PetscMPIInt size; 984 #if defined(PETSC_HAVE_SAWS) 985 PetscBool issaws; 986 #endif 987 988 PetscFunctionBegin; 989 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 990 PetscValidType(mat,1); 991 if (!viewer) { 992 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 993 } 994 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 995 PetscCheckSameComm(mat,1,viewer,2); 996 MatCheckPreallocated(mat,1); 997 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 998 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 999 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1000 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 1001 if (ibinary) { 1002 PetscBool mpiio; 1003 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 1004 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 1005 } 1006 1007 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1008 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1009 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1010 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 1011 } 1012 1013 #if defined(PETSC_HAVE_SAWS) 1014 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1015 #endif 1016 if (iascii) { 1017 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1018 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1019 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1020 MatNullSpace nullsp,transnullsp; 1021 1022 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1023 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1024 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1025 if (rbs != 1 || cbs != 1) { 1026 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1027 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1028 } else { 1029 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1030 } 1031 if (mat->factortype) { 1032 MatSolverType solver; 1033 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1034 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1035 } 1036 if (mat->ops->getinfo) { 1037 MatInfo info; 1038 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1039 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1040 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1041 } 1042 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1043 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1044 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1045 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1046 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1047 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1048 } 1049 #if defined(PETSC_HAVE_SAWS) 1050 } else if (issaws) { 1051 PetscMPIInt rank; 1052 1053 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1054 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1055 if (!((PetscObject)mat)->amsmem && !rank) { 1056 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1057 } 1058 #endif 1059 } 1060 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1061 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1062 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1063 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1064 } else if (mat->ops->view) { 1065 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1066 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1067 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1068 } 1069 if (iascii) { 1070 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1071 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1072 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1073 } 1074 } 1075 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1076 PetscFunctionReturn(0); 1077 } 1078 1079 #if defined(PETSC_USE_DEBUG) 1080 #include <../src/sys/totalview/tv_data_display.h> 1081 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1082 { 1083 TV_add_row("Local rows", "int", &mat->rmap->n); 1084 TV_add_row("Local columns", "int", &mat->cmap->n); 1085 TV_add_row("Global rows", "int", &mat->rmap->N); 1086 TV_add_row("Global columns", "int", &mat->cmap->N); 1087 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1088 return TV_format_OK; 1089 } 1090 #endif 1091 1092 /*@C 1093 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1094 with MatView(). The matrix format is determined from the options database. 1095 Generates a parallel MPI matrix if the communicator has more than one 1096 processor. The default matrix type is AIJ. 1097 1098 Collective on PetscViewer 1099 1100 Input Parameters: 1101 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1102 or some related function before a call to MatLoad() 1103 - viewer - binary/HDF5 file viewer 1104 1105 Options Database Keys: 1106 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1107 block size 1108 . -matload_block_size <bs> 1109 1110 Level: beginner 1111 1112 Notes: 1113 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1114 Mat before calling this routine if you wish to set it from the options database. 1115 1116 MatLoad() automatically loads into the options database any options 1117 given in the file filename.info where filename is the name of the file 1118 that was passed to the PetscViewerBinaryOpen(). The options in the info 1119 file will be ignored if you use the -viewer_binary_skip_info option. 1120 1121 If the type or size of newmat is not set before a call to MatLoad, PETSc 1122 sets the default matrix type AIJ and sets the local and global sizes. 1123 If type and/or size is already set, then the same are used. 1124 1125 In parallel, each processor can load a subset of rows (or the 1126 entire matrix). This routine is especially useful when a large 1127 matrix is stored on disk and only part of it is desired on each 1128 processor. For example, a parallel solver may access only some of 1129 the rows from each processor. The algorithm used here reads 1130 relatively small blocks of data rather than reading the entire 1131 matrix and then subsetting it. 1132 1133 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1134 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1135 or the sequence like 1136 $ PetscViewer v; 1137 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1138 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1139 $ PetscViewerSetFromOptions(v); 1140 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1141 $ PetscViewerFileSetName(v,"datafile"); 1142 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1143 $ -viewer_type {binary,hdf5} 1144 1145 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1146 and src/mat/examples/tutorials/ex10.c with the second approach. 1147 1148 Notes about the PETSc binary format: 1149 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1150 is read onto rank 0 and then shipped to its destination rank, one after another. 1151 Multiple objects, both matrices and vectors, can be stored within the same file. 1152 Their PetscObject name is ignored; they are loaded in the order of their storage. 1153 1154 Most users should not need to know the details of the binary storage 1155 format, since MatLoad() and MatView() completely hide these details. 1156 But for anyone who's interested, the standard binary matrix storage 1157 format is 1158 1159 $ int MAT_FILE_CLASSID 1160 $ int number of rows 1161 $ int number of columns 1162 $ int total number of nonzeros 1163 $ int *number nonzeros in each row 1164 $ int *column indices of all nonzeros (starting index is zero) 1165 $ PetscScalar *values of all nonzeros 1166 1167 PETSc automatically does the byte swapping for 1168 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1169 linux, Windows and the paragon; thus if you write your own binary 1170 read/write routines you have to swap the bytes; see PetscBinaryRead() 1171 and PetscBinaryWrite() to see how this may be done. 1172 1173 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1174 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1175 Each processor's chunk is loaded independently by its owning rank. 1176 Multiple objects, both matrices and vectors, can be stored within the same file. 1177 They are looked up by their PetscObject name. 1178 1179 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1180 by default the same structure and naming of the AIJ arrays and column count 1181 (see PetscViewerHDF5SetAIJNames()) 1182 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1183 $ save example.mat A b -v7.3 1184 can be directly read by this routine (see Reference 1 for details). 1185 Note that depending on your MATLAB version, this format might be a default, 1186 otherwise you can set it as default in Preferences. 1187 1188 Unless -nocompression flag is used to save the file in MATLAB, 1189 PETSc must be configured with ZLIB package. 1190 1191 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1192 1193 Current HDF5 (MAT-File) limitations: 1194 This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices. 1195 1196 Corresponding MatView() is not yet implemented. 1197 1198 The loaded matrix is actually a transpose of the original one in MATLAB, 1199 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1200 With this format, matrix is automatically transposed by PETSc, 1201 unless the matrix is marked as SPD or symmetric 1202 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1203 1204 References: 1205 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1206 1207 .keywords: matrix, load, binary, input, HDF5 1208 1209 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), MatView(), VecLoad() 1210 1211 @*/ 1212 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1213 { 1214 PetscErrorCode ierr; 1215 PetscBool flg; 1216 1217 PetscFunctionBegin; 1218 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1219 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1220 1221 if (!((PetscObject)newmat)->type_name) { 1222 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1223 } 1224 1225 flg = PETSC_FALSE; 1226 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1227 if (flg) { 1228 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1229 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1230 } 1231 flg = PETSC_FALSE; 1232 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1233 if (flg) { 1234 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1235 } 1236 1237 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1238 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1239 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1240 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1241 PetscFunctionReturn(0); 1242 } 1243 1244 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1245 { 1246 PetscErrorCode ierr; 1247 Mat_Redundant *redund = *redundant; 1248 PetscInt i; 1249 1250 PetscFunctionBegin; 1251 if (redund){ 1252 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1253 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1254 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1255 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1256 } else { 1257 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1258 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1259 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1260 for (i=0; i<redund->nrecvs; i++) { 1261 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1262 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1263 } 1264 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1265 } 1266 1267 if (redund->subcomm) { 1268 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1269 } 1270 ierr = PetscFree(redund);CHKERRQ(ierr); 1271 } 1272 PetscFunctionReturn(0); 1273 } 1274 1275 /*@ 1276 MatDestroy - Frees space taken by a matrix. 1277 1278 Collective on Mat 1279 1280 Input Parameter: 1281 . A - the matrix 1282 1283 Level: beginner 1284 1285 @*/ 1286 PetscErrorCode MatDestroy(Mat *A) 1287 { 1288 PetscErrorCode ierr; 1289 1290 PetscFunctionBegin; 1291 if (!*A) PetscFunctionReturn(0); 1292 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1293 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1294 1295 /* if memory was published with SAWs then destroy it */ 1296 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1297 if ((*A)->ops->destroy) { 1298 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1299 } 1300 1301 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1302 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1303 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1304 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1305 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1306 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1307 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1308 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1309 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1310 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1311 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1312 PetscFunctionReturn(0); 1313 } 1314 1315 /*@C 1316 MatSetValues - Inserts or adds a block of values into a matrix. 1317 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1318 MUST be called after all calls to MatSetValues() have been completed. 1319 1320 Not Collective 1321 1322 Input Parameters: 1323 + mat - the matrix 1324 . v - a logically two-dimensional array of values 1325 . m, idxm - the number of rows and their global indices 1326 . n, idxn - the number of columns and their global indices 1327 - addv - either ADD_VALUES or INSERT_VALUES, where 1328 ADD_VALUES adds values to any existing entries, and 1329 INSERT_VALUES replaces existing entries with new values 1330 1331 Notes: 1332 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1333 MatSetUp() before using this routine 1334 1335 By default the values, v, are row-oriented. See MatSetOption() for other options. 1336 1337 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1338 options cannot be mixed without intervening calls to the assembly 1339 routines. 1340 1341 MatSetValues() uses 0-based row and column numbers in Fortran 1342 as well as in C. 1343 1344 Negative indices may be passed in idxm and idxn, these rows and columns are 1345 simply ignored. This allows easily inserting element stiffness matrices 1346 with homogeneous Dirchlet boundary conditions that you don't want represented 1347 in the matrix. 1348 1349 Efficiency Alert: 1350 The routine MatSetValuesBlocked() may offer much better efficiency 1351 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1352 1353 Level: beginner 1354 1355 Developer Notes: 1356 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1357 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1358 1359 Concepts: matrices^putting entries in 1360 1361 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1362 InsertMode, INSERT_VALUES, ADD_VALUES 1363 @*/ 1364 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1365 { 1366 PetscErrorCode ierr; 1367 #if defined(PETSC_USE_DEBUG) 1368 PetscInt i,j; 1369 #endif 1370 1371 PetscFunctionBeginHot; 1372 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1373 PetscValidType(mat,1); 1374 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1375 PetscValidIntPointer(idxm,3); 1376 PetscValidIntPointer(idxn,5); 1377 PetscValidScalarPointer(v,6); 1378 MatCheckPreallocated(mat,1); 1379 if (mat->insertmode == NOT_SET_VALUES) { 1380 mat->insertmode = addv; 1381 } 1382 #if defined(PETSC_USE_DEBUG) 1383 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1384 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1385 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1386 1387 for (i=0; i<m; i++) { 1388 for (j=0; j<n; j++) { 1389 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1390 #if defined(PETSC_USE_COMPLEX) 1391 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]); 1392 #else 1393 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1394 #endif 1395 } 1396 } 1397 #endif 1398 1399 if (mat->assembled) { 1400 mat->was_assembled = PETSC_TRUE; 1401 mat->assembled = PETSC_FALSE; 1402 } 1403 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1404 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1405 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1406 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1407 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1408 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1409 } 1410 #endif 1411 PetscFunctionReturn(0); 1412 } 1413 1414 1415 /*@ 1416 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1417 values into a matrix 1418 1419 Not Collective 1420 1421 Input Parameters: 1422 + mat - the matrix 1423 . row - the (block) row to set 1424 - v - a logically two-dimensional array of values 1425 1426 Notes: 1427 By the values, v, are column-oriented (for the block version) and sorted 1428 1429 All the nonzeros in the row must be provided 1430 1431 The matrix must have previously had its column indices set 1432 1433 The row must belong to this process 1434 1435 Level: intermediate 1436 1437 Concepts: matrices^putting entries in 1438 1439 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1440 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1441 @*/ 1442 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1443 { 1444 PetscErrorCode ierr; 1445 PetscInt globalrow; 1446 1447 PetscFunctionBegin; 1448 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1449 PetscValidType(mat,1); 1450 PetscValidScalarPointer(v,2); 1451 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1452 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1453 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1454 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1455 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1456 } 1457 #endif 1458 PetscFunctionReturn(0); 1459 } 1460 1461 /*@ 1462 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1463 values into a matrix 1464 1465 Not Collective 1466 1467 Input Parameters: 1468 + mat - the matrix 1469 . row - the (block) row to set 1470 - 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 1471 1472 Notes: 1473 The values, v, are column-oriented for the block version. 1474 1475 All the nonzeros in the row must be provided 1476 1477 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1478 1479 The row must belong to this process 1480 1481 Level: advanced 1482 1483 Concepts: matrices^putting entries in 1484 1485 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1486 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1487 @*/ 1488 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1489 { 1490 PetscErrorCode ierr; 1491 1492 PetscFunctionBeginHot; 1493 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1494 PetscValidType(mat,1); 1495 MatCheckPreallocated(mat,1); 1496 PetscValidScalarPointer(v,2); 1497 #if defined(PETSC_USE_DEBUG) 1498 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1499 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1500 #endif 1501 mat->insertmode = INSERT_VALUES; 1502 1503 if (mat->assembled) { 1504 mat->was_assembled = PETSC_TRUE; 1505 mat->assembled = PETSC_FALSE; 1506 } 1507 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1508 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1509 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1510 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1511 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1512 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1513 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1514 } 1515 #endif 1516 PetscFunctionReturn(0); 1517 } 1518 1519 /*@ 1520 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1521 Using structured grid indexing 1522 1523 Not Collective 1524 1525 Input Parameters: 1526 + mat - the matrix 1527 . m - number of rows being entered 1528 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1529 . n - number of columns being entered 1530 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1531 . v - a logically two-dimensional array of values 1532 - addv - either ADD_VALUES or INSERT_VALUES, where 1533 ADD_VALUES adds values to any existing entries, and 1534 INSERT_VALUES replaces existing entries with new values 1535 1536 Notes: 1537 By default the values, v, are row-oriented. See MatSetOption() for other options. 1538 1539 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1540 options cannot be mixed without intervening calls to the assembly 1541 routines. 1542 1543 The grid coordinates are across the entire grid, not just the local portion 1544 1545 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1546 as well as in C. 1547 1548 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1549 1550 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1551 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1552 1553 The columns and rows in the stencil passed in MUST be contained within the 1554 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1555 if you create a DMDA with an overlap of one grid level and on a particular process its first 1556 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1557 first i index you can use in your column and row indices in MatSetStencil() is 5. 1558 1559 In Fortran idxm and idxn should be declared as 1560 $ MatStencil idxm(4,m),idxn(4,n) 1561 and the values inserted using 1562 $ idxm(MatStencil_i,1) = i 1563 $ idxm(MatStencil_j,1) = j 1564 $ idxm(MatStencil_k,1) = k 1565 $ idxm(MatStencil_c,1) = c 1566 etc 1567 1568 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1569 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1570 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1571 DM_BOUNDARY_PERIODIC boundary type. 1572 1573 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 1574 a single value per point) you can skip filling those indices. 1575 1576 Inspired by the structured grid interface to the HYPRE package 1577 (http://www.llnl.gov/CASC/hypre) 1578 1579 Efficiency Alert: 1580 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1581 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1582 1583 Level: beginner 1584 1585 Concepts: matrices^putting entries in 1586 1587 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1588 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1589 @*/ 1590 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1591 { 1592 PetscErrorCode ierr; 1593 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1594 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1595 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1596 1597 PetscFunctionBegin; 1598 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1599 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1600 PetscValidType(mat,1); 1601 PetscValidIntPointer(idxm,3); 1602 PetscValidIntPointer(idxn,5); 1603 PetscValidScalarPointer(v,6); 1604 1605 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1606 jdxm = buf; jdxn = buf+m; 1607 } else { 1608 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1609 jdxm = bufm; jdxn = bufn; 1610 } 1611 for (i=0; i<m; i++) { 1612 for (j=0; j<3-sdim; j++) dxm++; 1613 tmp = *dxm++ - starts[0]; 1614 for (j=0; j<dim-1; j++) { 1615 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1616 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1617 } 1618 if (mat->stencil.noc) dxm++; 1619 jdxm[i] = tmp; 1620 } 1621 for (i=0; i<n; i++) { 1622 for (j=0; j<3-sdim; j++) dxn++; 1623 tmp = *dxn++ - starts[0]; 1624 for (j=0; j<dim-1; j++) { 1625 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1626 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1627 } 1628 if (mat->stencil.noc) dxn++; 1629 jdxn[i] = tmp; 1630 } 1631 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1632 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1633 PetscFunctionReturn(0); 1634 } 1635 1636 /*@ 1637 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1638 Using structured grid indexing 1639 1640 Not Collective 1641 1642 Input Parameters: 1643 + mat - the matrix 1644 . m - number of rows being entered 1645 . idxm - grid coordinates for matrix rows being entered 1646 . n - number of columns being entered 1647 . idxn - grid coordinates for matrix columns being entered 1648 . v - a logically two-dimensional array of values 1649 - addv - either ADD_VALUES or INSERT_VALUES, where 1650 ADD_VALUES adds values to any existing entries, and 1651 INSERT_VALUES replaces existing entries with new values 1652 1653 Notes: 1654 By default the values, v, are row-oriented and unsorted. 1655 See MatSetOption() for other options. 1656 1657 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1658 options cannot be mixed without intervening calls to the assembly 1659 routines. 1660 1661 The grid coordinates are across the entire grid, not just the local portion 1662 1663 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1664 as well as in C. 1665 1666 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1667 1668 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1669 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1670 1671 The columns and rows in the stencil passed in MUST be contained within the 1672 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1673 if you create a DMDA with an overlap of one grid level and on a particular process its first 1674 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1675 first i index you can use in your column and row indices in MatSetStencil() is 5. 1676 1677 In Fortran idxm and idxn should be declared as 1678 $ MatStencil idxm(4,m),idxn(4,n) 1679 and the values inserted using 1680 $ idxm(MatStencil_i,1) = i 1681 $ idxm(MatStencil_j,1) = j 1682 $ idxm(MatStencil_k,1) = k 1683 etc 1684 1685 Negative indices may be passed in idxm and idxn, these rows and columns are 1686 simply ignored. This allows easily inserting element stiffness matrices 1687 with homogeneous Dirchlet boundary conditions that you don't want represented 1688 in the matrix. 1689 1690 Inspired by the structured grid interface to the HYPRE package 1691 (http://www.llnl.gov/CASC/hypre) 1692 1693 Level: beginner 1694 1695 Concepts: matrices^putting entries in 1696 1697 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1698 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1699 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1700 @*/ 1701 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1702 { 1703 PetscErrorCode ierr; 1704 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1705 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1706 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1707 1708 PetscFunctionBegin; 1709 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1710 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1711 PetscValidType(mat,1); 1712 PetscValidIntPointer(idxm,3); 1713 PetscValidIntPointer(idxn,5); 1714 PetscValidScalarPointer(v,6); 1715 1716 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1717 jdxm = buf; jdxn = buf+m; 1718 } else { 1719 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1720 jdxm = bufm; jdxn = bufn; 1721 } 1722 for (i=0; i<m; i++) { 1723 for (j=0; j<3-sdim; j++) dxm++; 1724 tmp = *dxm++ - starts[0]; 1725 for (j=0; j<sdim-1; j++) { 1726 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1727 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1728 } 1729 dxm++; 1730 jdxm[i] = tmp; 1731 } 1732 for (i=0; i<n; i++) { 1733 for (j=0; j<3-sdim; j++) dxn++; 1734 tmp = *dxn++ - starts[0]; 1735 for (j=0; j<sdim-1; j++) { 1736 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1737 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1738 } 1739 dxn++; 1740 jdxn[i] = tmp; 1741 } 1742 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1743 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1744 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1745 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1746 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1747 } 1748 #endif 1749 PetscFunctionReturn(0); 1750 } 1751 1752 /*@ 1753 MatSetStencil - Sets the grid information for setting values into a matrix via 1754 MatSetValuesStencil() 1755 1756 Not Collective 1757 1758 Input Parameters: 1759 + mat - the matrix 1760 . dim - dimension of the grid 1, 2, or 3 1761 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1762 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1763 - dof - number of degrees of freedom per node 1764 1765 1766 Inspired by the structured grid interface to the HYPRE package 1767 (www.llnl.gov/CASC/hyper) 1768 1769 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1770 user. 1771 1772 Level: beginner 1773 1774 Concepts: matrices^putting entries in 1775 1776 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1777 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1778 @*/ 1779 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1780 { 1781 PetscInt i; 1782 1783 PetscFunctionBegin; 1784 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1785 PetscValidIntPointer(dims,3); 1786 PetscValidIntPointer(starts,4); 1787 1788 mat->stencil.dim = dim + (dof > 1); 1789 for (i=0; i<dim; i++) { 1790 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1791 mat->stencil.starts[i] = starts[dim-i-1]; 1792 } 1793 mat->stencil.dims[dim] = dof; 1794 mat->stencil.starts[dim] = 0; 1795 mat->stencil.noc = (PetscBool)(dof == 1); 1796 PetscFunctionReturn(0); 1797 } 1798 1799 /*@C 1800 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1801 1802 Not Collective 1803 1804 Input Parameters: 1805 + mat - the matrix 1806 . v - a logically two-dimensional array of values 1807 . m, idxm - the number of block rows and their global block indices 1808 . n, idxn - the number of block columns and their global block indices 1809 - addv - either ADD_VALUES or INSERT_VALUES, where 1810 ADD_VALUES adds values to any existing entries, and 1811 INSERT_VALUES replaces existing entries with new values 1812 1813 Notes: 1814 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1815 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1816 1817 The m and n count the NUMBER of blocks in the row direction and column direction, 1818 NOT the total number of rows/columns; for example, if the block size is 2 and 1819 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1820 The values in idxm would be 1 2; that is the first index for each block divided by 1821 the block size. 1822 1823 Note that you must call MatSetBlockSize() when constructing this matrix (before 1824 preallocating it). 1825 1826 By default the values, v, are row-oriented, so the layout of 1827 v is the same as for MatSetValues(). See MatSetOption() for other options. 1828 1829 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1830 options cannot be mixed without intervening calls to the assembly 1831 routines. 1832 1833 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1834 as well as in C. 1835 1836 Negative indices may be passed in idxm and idxn, these rows and columns are 1837 simply ignored. This allows easily inserting element stiffness matrices 1838 with homogeneous Dirchlet boundary conditions that you don't want represented 1839 in the matrix. 1840 1841 Each time an entry is set within a sparse matrix via MatSetValues(), 1842 internal searching must be done to determine where to place the 1843 data in the matrix storage space. By instead inserting blocks of 1844 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1845 reduced. 1846 1847 Example: 1848 $ Suppose m=n=2 and block size(bs) = 2 The array is 1849 $ 1850 $ 1 2 | 3 4 1851 $ 5 6 | 7 8 1852 $ - - - | - - - 1853 $ 9 10 | 11 12 1854 $ 13 14 | 15 16 1855 $ 1856 $ v[] should be passed in like 1857 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1858 $ 1859 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1860 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1861 1862 Level: intermediate 1863 1864 Concepts: matrices^putting entries in blocked 1865 1866 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1867 @*/ 1868 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1869 { 1870 PetscErrorCode ierr; 1871 1872 PetscFunctionBeginHot; 1873 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1874 PetscValidType(mat,1); 1875 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1876 PetscValidIntPointer(idxm,3); 1877 PetscValidIntPointer(idxn,5); 1878 PetscValidScalarPointer(v,6); 1879 MatCheckPreallocated(mat,1); 1880 if (mat->insertmode == NOT_SET_VALUES) { 1881 mat->insertmode = addv; 1882 } 1883 #if defined(PETSC_USE_DEBUG) 1884 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1885 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1886 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1887 #endif 1888 1889 if (mat->assembled) { 1890 mat->was_assembled = PETSC_TRUE; 1891 mat->assembled = PETSC_FALSE; 1892 } 1893 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1894 if (mat->ops->setvaluesblocked) { 1895 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1896 } else { 1897 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1898 PetscInt i,j,bs,cbs; 1899 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1900 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1901 iidxm = buf; iidxn = buf + m*bs; 1902 } else { 1903 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1904 iidxm = bufr; iidxn = bufc; 1905 } 1906 for (i=0; i<m; i++) { 1907 for (j=0; j<bs; j++) { 1908 iidxm[i*bs+j] = bs*idxm[i] + j; 1909 } 1910 } 1911 for (i=0; i<n; i++) { 1912 for (j=0; j<cbs; j++) { 1913 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1914 } 1915 } 1916 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1917 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1918 } 1919 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1920 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1921 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1922 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1923 } 1924 #endif 1925 PetscFunctionReturn(0); 1926 } 1927 1928 /*@ 1929 MatGetValues - Gets a block of values from a matrix. 1930 1931 Not Collective; currently only returns a local block 1932 1933 Input Parameters: 1934 + mat - the matrix 1935 . v - a logically two-dimensional array for storing the values 1936 . m, idxm - the number of rows and their global indices 1937 - n, idxn - the number of columns and their global indices 1938 1939 Notes: 1940 The user must allocate space (m*n PetscScalars) for the values, v. 1941 The values, v, are then returned in a row-oriented format, 1942 analogous to that used by default in MatSetValues(). 1943 1944 MatGetValues() uses 0-based row and column numbers in 1945 Fortran as well as in C. 1946 1947 MatGetValues() requires that the matrix has been assembled 1948 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1949 MatSetValues() and MatGetValues() CANNOT be made in succession 1950 without intermediate matrix assembly. 1951 1952 Negative row or column indices will be ignored and those locations in v[] will be 1953 left unchanged. 1954 1955 Level: advanced 1956 1957 Concepts: matrices^accessing values 1958 1959 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1960 @*/ 1961 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1962 { 1963 PetscErrorCode ierr; 1964 1965 PetscFunctionBegin; 1966 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1967 PetscValidType(mat,1); 1968 if (!m || !n) PetscFunctionReturn(0); 1969 PetscValidIntPointer(idxm,3); 1970 PetscValidIntPointer(idxn,5); 1971 PetscValidScalarPointer(v,6); 1972 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1973 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1974 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1975 MatCheckPreallocated(mat,1); 1976 1977 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1978 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1979 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1980 PetscFunctionReturn(0); 1981 } 1982 1983 /*@ 1984 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1985 the same size. Currently, this can only be called once and creates the given matrix. 1986 1987 Not Collective 1988 1989 Input Parameters: 1990 + mat - the matrix 1991 . nb - the number of blocks 1992 . bs - the number of rows (and columns) in each block 1993 . rows - a concatenation of the rows for each block 1994 - v - a concatenation of logically two-dimensional arrays of values 1995 1996 Notes: 1997 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1998 1999 Level: advanced 2000 2001 Concepts: matrices^putting entries in 2002 2003 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 2004 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 2005 @*/ 2006 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2007 { 2008 PetscErrorCode ierr; 2009 2010 PetscFunctionBegin; 2011 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2012 PetscValidType(mat,1); 2013 PetscValidScalarPointer(rows,4); 2014 PetscValidScalarPointer(v,5); 2015 #if defined(PETSC_USE_DEBUG) 2016 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2017 #endif 2018 2019 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2020 if (mat->ops->setvaluesbatch) { 2021 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 2022 } else { 2023 PetscInt b; 2024 for (b = 0; b < nb; ++b) { 2025 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 2026 } 2027 } 2028 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2029 PetscFunctionReturn(0); 2030 } 2031 2032 /*@ 2033 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2034 the routine MatSetValuesLocal() to allow users to insert matrix entries 2035 using a local (per-processor) numbering. 2036 2037 Not Collective 2038 2039 Input Parameters: 2040 + x - the matrix 2041 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2042 - cmapping - column mapping 2043 2044 Level: intermediate 2045 2046 Concepts: matrices^local to global mapping 2047 Concepts: local to global mapping^for matrices 2048 2049 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 2050 @*/ 2051 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2052 { 2053 PetscErrorCode ierr; 2054 2055 PetscFunctionBegin; 2056 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2057 PetscValidType(x,1); 2058 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2059 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2060 2061 if (x->ops->setlocaltoglobalmapping) { 2062 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2063 } else { 2064 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2065 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2066 } 2067 PetscFunctionReturn(0); 2068 } 2069 2070 2071 /*@ 2072 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2073 2074 Not Collective 2075 2076 Input Parameters: 2077 . A - the matrix 2078 2079 Output Parameters: 2080 + rmapping - row mapping 2081 - cmapping - column mapping 2082 2083 Level: advanced 2084 2085 Concepts: matrices^local to global mapping 2086 Concepts: local to global mapping^for matrices 2087 2088 .seealso: MatSetValuesLocal() 2089 @*/ 2090 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2091 { 2092 PetscFunctionBegin; 2093 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2094 PetscValidType(A,1); 2095 if (rmapping) PetscValidPointer(rmapping,2); 2096 if (cmapping) PetscValidPointer(cmapping,3); 2097 if (rmapping) *rmapping = A->rmap->mapping; 2098 if (cmapping) *cmapping = A->cmap->mapping; 2099 PetscFunctionReturn(0); 2100 } 2101 2102 /*@ 2103 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2104 2105 Not Collective 2106 2107 Input Parameters: 2108 . A - the matrix 2109 2110 Output Parameters: 2111 + rmap - row layout 2112 - cmap - column layout 2113 2114 Level: advanced 2115 2116 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2117 @*/ 2118 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2119 { 2120 PetscFunctionBegin; 2121 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2122 PetscValidType(A,1); 2123 if (rmap) PetscValidPointer(rmap,2); 2124 if (cmap) PetscValidPointer(cmap,3); 2125 if (rmap) *rmap = A->rmap; 2126 if (cmap) *cmap = A->cmap; 2127 PetscFunctionReturn(0); 2128 } 2129 2130 /*@C 2131 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2132 using a local ordering of the nodes. 2133 2134 Not Collective 2135 2136 Input Parameters: 2137 + mat - the matrix 2138 . nrow, irow - number of rows and their local indices 2139 . ncol, icol - number of columns and their local indices 2140 . y - a logically two-dimensional array of values 2141 - addv - either INSERT_VALUES or ADD_VALUES, where 2142 ADD_VALUES adds values to any existing entries, and 2143 INSERT_VALUES replaces existing entries with new values 2144 2145 Notes: 2146 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2147 MatSetUp() before using this routine 2148 2149 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2150 2151 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2152 options cannot be mixed without intervening calls to the assembly 2153 routines. 2154 2155 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2156 MUST be called after all calls to MatSetValuesLocal() have been completed. 2157 2158 Level: intermediate 2159 2160 Concepts: matrices^putting entries in with local numbering 2161 2162 Developer Notes: 2163 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2164 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2165 2166 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2167 MatSetValueLocal() 2168 @*/ 2169 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2170 { 2171 PetscErrorCode ierr; 2172 2173 PetscFunctionBeginHot; 2174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2175 PetscValidType(mat,1); 2176 MatCheckPreallocated(mat,1); 2177 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2178 PetscValidIntPointer(irow,3); 2179 PetscValidIntPointer(icol,5); 2180 PetscValidScalarPointer(y,6); 2181 if (mat->insertmode == NOT_SET_VALUES) { 2182 mat->insertmode = addv; 2183 } 2184 #if defined(PETSC_USE_DEBUG) 2185 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2186 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2187 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2188 #endif 2189 2190 if (mat->assembled) { 2191 mat->was_assembled = PETSC_TRUE; 2192 mat->assembled = PETSC_FALSE; 2193 } 2194 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2195 if (mat->ops->setvalueslocal) { 2196 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2197 } else { 2198 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2199 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2200 irowm = buf; icolm = buf+nrow; 2201 } else { 2202 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2203 irowm = bufr; icolm = bufc; 2204 } 2205 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2206 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2207 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2208 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2209 } 2210 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2211 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2212 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2213 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2214 } 2215 #endif 2216 PetscFunctionReturn(0); 2217 } 2218 2219 /*@C 2220 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2221 using a local ordering of the nodes a block at a time. 2222 2223 Not Collective 2224 2225 Input Parameters: 2226 + x - the matrix 2227 . nrow, irow - number of rows and their local indices 2228 . ncol, icol - number of columns and their local indices 2229 . y - a logically two-dimensional array of values 2230 - addv - either INSERT_VALUES or ADD_VALUES, where 2231 ADD_VALUES adds values to any existing entries, and 2232 INSERT_VALUES replaces existing entries with new values 2233 2234 Notes: 2235 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2236 MatSetUp() before using this routine 2237 2238 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2239 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2240 2241 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2242 options cannot be mixed without intervening calls to the assembly 2243 routines. 2244 2245 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2246 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2247 2248 Level: intermediate 2249 2250 Developer Notes: 2251 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2252 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2253 2254 Concepts: matrices^putting blocked values in with local numbering 2255 2256 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2257 MatSetValuesLocal(), MatSetValuesBlocked() 2258 @*/ 2259 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2260 { 2261 PetscErrorCode ierr; 2262 2263 PetscFunctionBeginHot; 2264 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2265 PetscValidType(mat,1); 2266 MatCheckPreallocated(mat,1); 2267 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2268 PetscValidIntPointer(irow,3); 2269 PetscValidIntPointer(icol,5); 2270 PetscValidScalarPointer(y,6); 2271 if (mat->insertmode == NOT_SET_VALUES) { 2272 mat->insertmode = addv; 2273 } 2274 #if defined(PETSC_USE_DEBUG) 2275 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2276 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2277 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); 2278 #endif 2279 2280 if (mat->assembled) { 2281 mat->was_assembled = PETSC_TRUE; 2282 mat->assembled = PETSC_FALSE; 2283 } 2284 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2285 if (mat->ops->setvaluesblockedlocal) { 2286 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2287 } else { 2288 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2289 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2290 irowm = buf; icolm = buf + nrow; 2291 } else { 2292 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2293 irowm = bufr; icolm = bufc; 2294 } 2295 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2296 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2297 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2298 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2299 } 2300 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2301 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2302 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2303 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2304 } 2305 #endif 2306 PetscFunctionReturn(0); 2307 } 2308 2309 /*@ 2310 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2311 2312 Collective on Mat and Vec 2313 2314 Input Parameters: 2315 + mat - the matrix 2316 - x - the vector to be multiplied 2317 2318 Output Parameters: 2319 . y - the result 2320 2321 Notes: 2322 The vectors x and y cannot be the same. I.e., one cannot 2323 call MatMult(A,y,y). 2324 2325 Level: developer 2326 2327 Concepts: matrix-vector product 2328 2329 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2330 @*/ 2331 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2332 { 2333 PetscErrorCode ierr; 2334 2335 PetscFunctionBegin; 2336 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2337 PetscValidType(mat,1); 2338 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2339 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2340 2341 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2342 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2343 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2344 MatCheckPreallocated(mat,1); 2345 2346 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2347 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2348 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2349 PetscFunctionReturn(0); 2350 } 2351 2352 /* --------------------------------------------------------*/ 2353 /*@ 2354 MatMult - Computes the matrix-vector product, y = Ax. 2355 2356 Neighbor-wise Collective on Mat and Vec 2357 2358 Input Parameters: 2359 + mat - the matrix 2360 - x - the vector to be multiplied 2361 2362 Output Parameters: 2363 . y - the result 2364 2365 Notes: 2366 The vectors x and y cannot be the same. I.e., one cannot 2367 call MatMult(A,y,y). 2368 2369 Level: beginner 2370 2371 Concepts: matrix-vector product 2372 2373 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2374 @*/ 2375 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2376 { 2377 PetscErrorCode ierr; 2378 2379 PetscFunctionBegin; 2380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2381 PetscValidType(mat,1); 2382 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2383 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2384 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2385 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2386 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2387 #if !defined(PETSC_HAVE_CONSTRAINTS) 2388 if (mat->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); 2389 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); 2390 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); 2391 #endif 2392 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2393 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2394 MatCheckPreallocated(mat,1); 2395 2396 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2397 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2398 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2399 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2400 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2401 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2402 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2403 PetscFunctionReturn(0); 2404 } 2405 2406 /*@ 2407 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2408 2409 Neighbor-wise Collective on Mat and Vec 2410 2411 Input Parameters: 2412 + mat - the matrix 2413 - x - the vector to be multiplied 2414 2415 Output Parameters: 2416 . y - the result 2417 2418 Notes: 2419 The vectors x and y cannot be the same. I.e., one cannot 2420 call MatMultTranspose(A,y,y). 2421 2422 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2423 use MatMultHermitianTranspose() 2424 2425 Level: beginner 2426 2427 Concepts: matrix vector product^transpose 2428 2429 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2430 @*/ 2431 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2432 { 2433 PetscErrorCode ierr; 2434 2435 PetscFunctionBegin; 2436 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2437 PetscValidType(mat,1); 2438 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2439 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2440 2441 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2442 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2443 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2444 #if !defined(PETSC_HAVE_CONSTRAINTS) 2445 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); 2446 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); 2447 #endif 2448 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2449 MatCheckPreallocated(mat,1); 2450 2451 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2452 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2453 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2454 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2455 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2456 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2457 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2458 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2459 PetscFunctionReturn(0); 2460 } 2461 2462 /*@ 2463 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2464 2465 Neighbor-wise Collective on Mat and Vec 2466 2467 Input Parameters: 2468 + mat - the matrix 2469 - x - the vector to be multilplied 2470 2471 Output Parameters: 2472 . y - the result 2473 2474 Notes: 2475 The vectors x and y cannot be the same. I.e., one cannot 2476 call MatMultHermitianTranspose(A,y,y). 2477 2478 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2479 2480 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2481 2482 Level: beginner 2483 2484 Concepts: matrix vector product^transpose 2485 2486 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2487 @*/ 2488 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2489 { 2490 PetscErrorCode ierr; 2491 Vec w; 2492 2493 PetscFunctionBegin; 2494 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2495 PetscValidType(mat,1); 2496 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2497 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2498 2499 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2500 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2501 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2502 #if !defined(PETSC_HAVE_CONSTRAINTS) 2503 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); 2504 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); 2505 #endif 2506 MatCheckPreallocated(mat,1); 2507 2508 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2509 if (mat->ops->multhermitiantranspose) { 2510 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2511 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2512 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2513 } else { 2514 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2515 ierr = VecCopy(x,w);CHKERRQ(ierr); 2516 ierr = VecConjugate(w);CHKERRQ(ierr); 2517 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2518 ierr = VecDestroy(&w);CHKERRQ(ierr); 2519 ierr = VecConjugate(y);CHKERRQ(ierr); 2520 } 2521 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2522 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2523 PetscFunctionReturn(0); 2524 } 2525 2526 /*@ 2527 MatMultAdd - Computes v3 = v2 + A * v1. 2528 2529 Neighbor-wise Collective on Mat and Vec 2530 2531 Input Parameters: 2532 + mat - the matrix 2533 - v1, v2 - the vectors 2534 2535 Output Parameters: 2536 . v3 - the result 2537 2538 Notes: 2539 The vectors v1 and v3 cannot be the same. I.e., one cannot 2540 call MatMultAdd(A,v1,v2,v1). 2541 2542 Level: beginner 2543 2544 Concepts: matrix vector product^addition 2545 2546 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2547 @*/ 2548 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2549 { 2550 PetscErrorCode ierr; 2551 2552 PetscFunctionBegin; 2553 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2554 PetscValidType(mat,1); 2555 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2556 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2557 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2558 2559 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2560 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2561 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); 2562 /* 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); 2563 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); */ 2564 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); 2565 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); 2566 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2567 MatCheckPreallocated(mat,1); 2568 2569 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2570 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2571 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2572 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2573 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2574 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2575 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2576 PetscFunctionReturn(0); 2577 } 2578 2579 /*@ 2580 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2581 2582 Neighbor-wise Collective on Mat and Vec 2583 2584 Input Parameters: 2585 + mat - the matrix 2586 - v1, v2 - the vectors 2587 2588 Output Parameters: 2589 . v3 - the result 2590 2591 Notes: 2592 The vectors v1 and v3 cannot be the same. I.e., one cannot 2593 call MatMultTransposeAdd(A,v1,v2,v1). 2594 2595 Level: beginner 2596 2597 Concepts: matrix vector product^transpose and addition 2598 2599 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2600 @*/ 2601 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2602 { 2603 PetscErrorCode ierr; 2604 2605 PetscFunctionBegin; 2606 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2607 PetscValidType(mat,1); 2608 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2609 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2610 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2611 2612 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2613 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2614 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2615 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2616 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); 2617 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); 2618 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); 2619 MatCheckPreallocated(mat,1); 2620 2621 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2622 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2623 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2624 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2625 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2626 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2627 PetscFunctionReturn(0); 2628 } 2629 2630 /*@ 2631 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2632 2633 Neighbor-wise Collective on Mat and Vec 2634 2635 Input Parameters: 2636 + mat - the matrix 2637 - v1, v2 - the vectors 2638 2639 Output Parameters: 2640 . v3 - the result 2641 2642 Notes: 2643 The vectors v1 and v3 cannot be the same. I.e., one cannot 2644 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2645 2646 Level: beginner 2647 2648 Concepts: matrix vector product^transpose and addition 2649 2650 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2651 @*/ 2652 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2653 { 2654 PetscErrorCode ierr; 2655 2656 PetscFunctionBegin; 2657 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2658 PetscValidType(mat,1); 2659 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2660 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2661 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2662 2663 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2664 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2665 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2666 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); 2667 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); 2668 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); 2669 MatCheckPreallocated(mat,1); 2670 2671 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2672 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2673 if (mat->ops->multhermitiantransposeadd) { 2674 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2675 } else { 2676 Vec w,z; 2677 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2678 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2679 ierr = VecConjugate(w);CHKERRQ(ierr); 2680 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2681 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2682 ierr = VecDestroy(&w);CHKERRQ(ierr); 2683 ierr = VecConjugate(z);CHKERRQ(ierr); 2684 if (v2 != v3) { 2685 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2686 } else { 2687 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2688 } 2689 ierr = VecDestroy(&z);CHKERRQ(ierr); 2690 } 2691 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2692 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2693 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2694 PetscFunctionReturn(0); 2695 } 2696 2697 /*@ 2698 MatMultConstrained - The inner multiplication routine for a 2699 constrained matrix P^T A P. 2700 2701 Neighbor-wise Collective on Mat and Vec 2702 2703 Input Parameters: 2704 + mat - the matrix 2705 - x - the vector to be multilplied 2706 2707 Output Parameters: 2708 . y - the result 2709 2710 Notes: 2711 The vectors x and y cannot be the same. I.e., one cannot 2712 call MatMult(A,y,y). 2713 2714 Level: beginner 2715 2716 .keywords: matrix, multiply, matrix-vector product, constraint 2717 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2718 @*/ 2719 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2720 { 2721 PetscErrorCode ierr; 2722 2723 PetscFunctionBegin; 2724 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2725 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2726 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2727 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2728 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2729 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2730 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); 2731 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); 2732 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); 2733 2734 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2735 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2736 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2737 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2738 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2739 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2740 PetscFunctionReturn(0); 2741 } 2742 2743 /*@ 2744 MatMultTransposeConstrained - The inner multiplication routine for a 2745 constrained matrix P^T A^T P. 2746 2747 Neighbor-wise Collective on Mat and Vec 2748 2749 Input Parameters: 2750 + mat - the matrix 2751 - x - the vector to be multilplied 2752 2753 Output Parameters: 2754 . y - the result 2755 2756 Notes: 2757 The vectors x and y cannot be the same. I.e., one cannot 2758 call MatMult(A,y,y). 2759 2760 Level: beginner 2761 2762 .keywords: matrix, multiply, matrix-vector product, constraint 2763 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2764 @*/ 2765 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2766 { 2767 PetscErrorCode ierr; 2768 2769 PetscFunctionBegin; 2770 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2771 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2772 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2773 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2774 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2775 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2776 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); 2777 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); 2778 2779 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2780 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2781 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2782 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2783 PetscFunctionReturn(0); 2784 } 2785 2786 /*@C 2787 MatGetFactorType - gets the type of factorization it is 2788 2789 Not Collective 2790 2791 Input Parameters: 2792 . mat - the matrix 2793 2794 Output Parameters: 2795 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2796 2797 Level: intermediate 2798 2799 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2800 @*/ 2801 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2802 { 2803 PetscFunctionBegin; 2804 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2805 PetscValidType(mat,1); 2806 PetscValidPointer(t,2); 2807 *t = mat->factortype; 2808 PetscFunctionReturn(0); 2809 } 2810 2811 /*@C 2812 MatSetFactorType - sets the type of factorization it is 2813 2814 Logically Collective on Mat 2815 2816 Input Parameters: 2817 + mat - the matrix 2818 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2819 2820 Level: intermediate 2821 2822 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2823 @*/ 2824 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2825 { 2826 PetscFunctionBegin; 2827 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2828 PetscValidType(mat,1); 2829 mat->factortype = t; 2830 PetscFunctionReturn(0); 2831 } 2832 2833 /* ------------------------------------------------------------*/ 2834 /*@C 2835 MatGetInfo - Returns information about matrix storage (number of 2836 nonzeros, memory, etc.). 2837 2838 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2839 2840 Input Parameters: 2841 . mat - the matrix 2842 2843 Output Parameters: 2844 + flag - flag indicating the type of parameters to be returned 2845 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2846 MAT_GLOBAL_SUM - sum over all processors) 2847 - info - matrix information context 2848 2849 Notes: 2850 The MatInfo context contains a variety of matrix data, including 2851 number of nonzeros allocated and used, number of mallocs during 2852 matrix assembly, etc. Additional information for factored matrices 2853 is provided (such as the fill ratio, number of mallocs during 2854 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2855 when using the runtime options 2856 $ -info -mat_view ::ascii_info 2857 2858 Example for C/C++ Users: 2859 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2860 data within the MatInfo context. For example, 2861 .vb 2862 MatInfo info; 2863 Mat A; 2864 double mal, nz_a, nz_u; 2865 2866 MatGetInfo(A,MAT_LOCAL,&info); 2867 mal = info.mallocs; 2868 nz_a = info.nz_allocated; 2869 .ve 2870 2871 Example for Fortran Users: 2872 Fortran users should declare info as a double precision 2873 array of dimension MAT_INFO_SIZE, and then extract the parameters 2874 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2875 a complete list of parameter names. 2876 .vb 2877 double precision info(MAT_INFO_SIZE) 2878 double precision mal, nz_a 2879 Mat A 2880 integer ierr 2881 2882 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2883 mal = info(MAT_INFO_MALLOCS) 2884 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2885 .ve 2886 2887 Level: intermediate 2888 2889 Concepts: matrices^getting information on 2890 2891 Developer Note: fortran interface is not autogenerated as the f90 2892 interface defintion cannot be generated correctly [due to MatInfo] 2893 2894 .seealso: MatStashGetInfo() 2895 2896 @*/ 2897 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2898 { 2899 PetscErrorCode ierr; 2900 2901 PetscFunctionBegin; 2902 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2903 PetscValidType(mat,1); 2904 PetscValidPointer(info,3); 2905 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2906 MatCheckPreallocated(mat,1); 2907 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2908 PetscFunctionReturn(0); 2909 } 2910 2911 /* 2912 This is used by external packages where it is not easy to get the info from the actual 2913 matrix factorization. 2914 */ 2915 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2916 { 2917 PetscErrorCode ierr; 2918 2919 PetscFunctionBegin; 2920 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2921 PetscFunctionReturn(0); 2922 } 2923 2924 /* ----------------------------------------------------------*/ 2925 2926 /*@C 2927 MatLUFactor - Performs in-place LU factorization of matrix. 2928 2929 Collective on Mat 2930 2931 Input Parameters: 2932 + mat - the matrix 2933 . row - row permutation 2934 . col - column permutation 2935 - info - options for factorization, includes 2936 $ fill - expected fill as ratio of original fill. 2937 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2938 $ Run with the option -info to determine an optimal value to use 2939 2940 Notes: 2941 Most users should employ the simplified KSP interface for linear solvers 2942 instead of working directly with matrix algebra routines such as this. 2943 See, e.g., KSPCreate(). 2944 2945 This changes the state of the matrix to a factored matrix; it cannot be used 2946 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2947 2948 Level: developer 2949 2950 Concepts: matrices^LU factorization 2951 2952 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2953 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2954 2955 Developer Note: fortran interface is not autogenerated as the f90 2956 interface defintion cannot be generated correctly [due to MatFactorInfo] 2957 2958 @*/ 2959 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2960 { 2961 PetscErrorCode ierr; 2962 MatFactorInfo tinfo; 2963 2964 PetscFunctionBegin; 2965 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2966 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2967 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2968 if (info) PetscValidPointer(info,4); 2969 PetscValidType(mat,1); 2970 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2971 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2972 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2973 MatCheckPreallocated(mat,1); 2974 if (!info) { 2975 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2976 info = &tinfo; 2977 } 2978 2979 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2980 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2981 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2982 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2983 PetscFunctionReturn(0); 2984 } 2985 2986 /*@C 2987 MatILUFactor - Performs in-place ILU factorization of matrix. 2988 2989 Collective on Mat 2990 2991 Input Parameters: 2992 + mat - the matrix 2993 . row - row permutation 2994 . col - column permutation 2995 - info - structure containing 2996 $ levels - number of levels of fill. 2997 $ expected fill - as ratio of original fill. 2998 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2999 missing diagonal entries) 3000 3001 Notes: 3002 Probably really in-place only when level of fill is zero, otherwise allocates 3003 new space to store factored matrix and deletes previous memory. 3004 3005 Most users should employ the simplified KSP interface for linear solvers 3006 instead of working directly with matrix algebra routines such as this. 3007 See, e.g., KSPCreate(). 3008 3009 Level: developer 3010 3011 Concepts: matrices^ILU factorization 3012 3013 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 3014 3015 Developer Note: fortran interface is not autogenerated as the f90 3016 interface defintion cannot be generated correctly [due to MatFactorInfo] 3017 3018 @*/ 3019 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3020 { 3021 PetscErrorCode ierr; 3022 3023 PetscFunctionBegin; 3024 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3025 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3026 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3027 PetscValidPointer(info,4); 3028 PetscValidType(mat,1); 3029 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3030 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3031 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3032 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3033 MatCheckPreallocated(mat,1); 3034 3035 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3036 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 3037 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3038 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3039 PetscFunctionReturn(0); 3040 } 3041 3042 /*@C 3043 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3044 Call this routine before calling MatLUFactorNumeric(). 3045 3046 Collective on Mat 3047 3048 Input Parameters: 3049 + fact - the factor matrix obtained with MatGetFactor() 3050 . mat - the matrix 3051 . row, col - row and column permutations 3052 - info - options for factorization, includes 3053 $ fill - expected fill as ratio of original fill. 3054 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3055 $ Run with the option -info to determine an optimal value to use 3056 3057 3058 Notes: 3059 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3060 3061 Most users should employ the simplified KSP interface for linear solvers 3062 instead of working directly with matrix algebra routines such as this. 3063 See, e.g., KSPCreate(). 3064 3065 Level: developer 3066 3067 Concepts: matrices^LU symbolic factorization 3068 3069 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 3070 3071 Developer Note: fortran interface is not autogenerated as the f90 3072 interface defintion cannot be generated correctly [due to MatFactorInfo] 3073 3074 @*/ 3075 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3076 { 3077 PetscErrorCode ierr; 3078 3079 PetscFunctionBegin; 3080 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3081 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3082 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3083 if (info) PetscValidPointer(info,4); 3084 PetscValidType(mat,1); 3085 PetscValidPointer(fact,5); 3086 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3087 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3088 if (!(fact)->ops->lufactorsymbolic) { 3089 MatSolverType spackage; 3090 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3091 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3092 } 3093 MatCheckPreallocated(mat,2); 3094 3095 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3096 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3097 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3098 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3099 PetscFunctionReturn(0); 3100 } 3101 3102 /*@C 3103 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3104 Call this routine after first calling MatLUFactorSymbolic(). 3105 3106 Collective on Mat 3107 3108 Input Parameters: 3109 + fact - the factor matrix obtained with MatGetFactor() 3110 . mat - the matrix 3111 - info - options for factorization 3112 3113 Notes: 3114 See MatLUFactor() for in-place factorization. See 3115 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3116 3117 Most users should employ the simplified KSP interface for linear solvers 3118 instead of working directly with matrix algebra routines such as this. 3119 See, e.g., KSPCreate(). 3120 3121 Level: developer 3122 3123 Concepts: matrices^LU numeric factorization 3124 3125 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3126 3127 Developer Note: fortran interface is not autogenerated as the f90 3128 interface defintion cannot be generated correctly [due to MatFactorInfo] 3129 3130 @*/ 3131 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3132 { 3133 PetscErrorCode ierr; 3134 3135 PetscFunctionBegin; 3136 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3137 PetscValidType(mat,1); 3138 PetscValidPointer(fact,2); 3139 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3140 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3141 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); 3142 3143 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3144 MatCheckPreallocated(mat,2); 3145 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3146 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3147 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3148 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3149 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3150 PetscFunctionReturn(0); 3151 } 3152 3153 /*@C 3154 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3155 symmetric matrix. 3156 3157 Collective on Mat 3158 3159 Input Parameters: 3160 + mat - the matrix 3161 . perm - row and column permutations 3162 - f - expected fill as ratio of original fill 3163 3164 Notes: 3165 See MatLUFactor() for the nonsymmetric case. See also 3166 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3167 3168 Most users should employ the simplified KSP interface for linear solvers 3169 instead of working directly with matrix algebra routines such as this. 3170 See, e.g., KSPCreate(). 3171 3172 Level: developer 3173 3174 Concepts: matrices^Cholesky factorization 3175 3176 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3177 MatGetOrdering() 3178 3179 Developer Note: fortran interface is not autogenerated as the f90 3180 interface defintion cannot be generated correctly [due to MatFactorInfo] 3181 3182 @*/ 3183 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3184 { 3185 PetscErrorCode ierr; 3186 3187 PetscFunctionBegin; 3188 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3189 PetscValidType(mat,1); 3190 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3191 if (info) PetscValidPointer(info,3); 3192 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3193 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3194 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3195 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); 3196 MatCheckPreallocated(mat,1); 3197 3198 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3199 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3200 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3201 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3202 PetscFunctionReturn(0); 3203 } 3204 3205 /*@C 3206 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3207 of a symmetric matrix. 3208 3209 Collective on Mat 3210 3211 Input Parameters: 3212 + fact - the factor matrix obtained with MatGetFactor() 3213 . mat - the matrix 3214 . perm - row and column permutations 3215 - info - options for factorization, includes 3216 $ fill - expected fill as ratio of original fill. 3217 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3218 $ Run with the option -info to determine an optimal value to use 3219 3220 Notes: 3221 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3222 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3223 3224 Most users should employ the simplified KSP interface for linear solvers 3225 instead of working directly with matrix algebra routines such as this. 3226 See, e.g., KSPCreate(). 3227 3228 Level: developer 3229 3230 Concepts: matrices^Cholesky symbolic factorization 3231 3232 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3233 MatGetOrdering() 3234 3235 Developer Note: fortran interface is not autogenerated as the f90 3236 interface defintion cannot be generated correctly [due to MatFactorInfo] 3237 3238 @*/ 3239 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3240 { 3241 PetscErrorCode ierr; 3242 3243 PetscFunctionBegin; 3244 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3245 PetscValidType(mat,1); 3246 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3247 if (info) PetscValidPointer(info,3); 3248 PetscValidPointer(fact,4); 3249 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3250 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3251 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3252 if (!(fact)->ops->choleskyfactorsymbolic) { 3253 MatSolverType spackage; 3254 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3255 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3256 } 3257 MatCheckPreallocated(mat,2); 3258 3259 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3260 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3261 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3262 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3263 PetscFunctionReturn(0); 3264 } 3265 3266 /*@C 3267 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3268 of a symmetric matrix. Call this routine after first calling 3269 MatCholeskyFactorSymbolic(). 3270 3271 Collective on Mat 3272 3273 Input Parameters: 3274 + fact - the factor matrix obtained with MatGetFactor() 3275 . mat - the initial matrix 3276 . info - options for factorization 3277 - fact - the symbolic factor of mat 3278 3279 3280 Notes: 3281 Most users should employ the simplified KSP interface for linear solvers 3282 instead of working directly with matrix algebra routines such as this. 3283 See, e.g., KSPCreate(). 3284 3285 Level: developer 3286 3287 Concepts: matrices^Cholesky numeric factorization 3288 3289 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3290 3291 Developer Note: fortran interface is not autogenerated as the f90 3292 interface defintion cannot be generated correctly [due to MatFactorInfo] 3293 3294 @*/ 3295 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3296 { 3297 PetscErrorCode ierr; 3298 3299 PetscFunctionBegin; 3300 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3301 PetscValidType(mat,1); 3302 PetscValidPointer(fact,2); 3303 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3304 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3305 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3306 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); 3307 MatCheckPreallocated(mat,2); 3308 3309 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3310 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3311 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3312 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3313 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3314 PetscFunctionReturn(0); 3315 } 3316 3317 /* ----------------------------------------------------------------*/ 3318 /*@ 3319 MatSolve - Solves A x = b, given a factored matrix. 3320 3321 Neighbor-wise Collective on Mat and Vec 3322 3323 Input Parameters: 3324 + mat - the factored matrix 3325 - b - the right-hand-side vector 3326 3327 Output Parameter: 3328 . x - the result vector 3329 3330 Notes: 3331 The vectors b and x cannot be the same. I.e., one cannot 3332 call MatSolve(A,x,x). 3333 3334 Notes: 3335 Most users should employ the simplified KSP interface for linear solvers 3336 instead of working directly with matrix algebra routines such as this. 3337 See, e.g., KSPCreate(). 3338 3339 Level: developer 3340 3341 Concepts: matrices^triangular solves 3342 3343 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3344 @*/ 3345 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3346 { 3347 PetscErrorCode ierr; 3348 3349 PetscFunctionBegin; 3350 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3351 PetscValidType(mat,1); 3352 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3353 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3354 PetscCheckSameComm(mat,1,b,2); 3355 PetscCheckSameComm(mat,1,x,3); 3356 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3357 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); 3358 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); 3359 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); 3360 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3361 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3362 MatCheckPreallocated(mat,1); 3363 3364 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3365 if (mat->factorerrortype) { 3366 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3367 ierr = VecSetInf(x);CHKERRQ(ierr); 3368 } else { 3369 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3370 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3371 } 3372 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3373 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3374 PetscFunctionReturn(0); 3375 } 3376 3377 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans) 3378 { 3379 PetscErrorCode ierr; 3380 Vec b,x; 3381 PetscInt m,N,i; 3382 PetscScalar *bb,*xx; 3383 PetscBool flg; 3384 3385 PetscFunctionBegin; 3386 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3387 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3388 ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3389 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 3390 3391 ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr); 3392 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3393 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3394 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3395 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3396 for (i=0; i<N; i++) { 3397 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3398 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3399 if (trans) { 3400 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3401 } else { 3402 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3403 } 3404 ierr = VecResetArray(x);CHKERRQ(ierr); 3405 ierr = VecResetArray(b);CHKERRQ(ierr); 3406 } 3407 ierr = VecDestroy(&b);CHKERRQ(ierr); 3408 ierr = VecDestroy(&x);CHKERRQ(ierr); 3409 ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr); 3410 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3411 PetscFunctionReturn(0); 3412 } 3413 3414 /*@ 3415 MatMatSolve - Solves A X = B, given a factored matrix. 3416 3417 Neighbor-wise Collective on Mat 3418 3419 Input Parameters: 3420 + A - the factored matrix 3421 - B - the right-hand-side matrix (dense matrix) 3422 3423 Output Parameter: 3424 . X - the result matrix (dense matrix) 3425 3426 Notes: 3427 The matrices b and x cannot be the same. I.e., one cannot 3428 call MatMatSolve(A,x,x). 3429 3430 Notes: 3431 Most users should usually employ the simplified KSP interface for linear solvers 3432 instead of working directly with matrix algebra routines such as this. 3433 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3434 at a time. 3435 3436 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3437 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3438 3439 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3440 3441 Level: developer 3442 3443 Concepts: matrices^triangular solves 3444 3445 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3446 @*/ 3447 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3448 { 3449 PetscErrorCode ierr; 3450 3451 PetscFunctionBegin; 3452 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3453 PetscValidType(A,1); 3454 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3455 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3456 PetscCheckSameComm(A,1,B,2); 3457 PetscCheckSameComm(A,1,X,3); 3458 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3459 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); 3460 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); 3461 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"); 3462 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3463 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3464 MatCheckPreallocated(A,1); 3465 3466 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3467 if (!A->ops->matsolve) { 3468 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3469 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3470 } else { 3471 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3472 } 3473 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3474 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3475 PetscFunctionReturn(0); 3476 } 3477 3478 /*@ 3479 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3480 3481 Neighbor-wise Collective on Mat 3482 3483 Input Parameters: 3484 + A - the factored matrix 3485 - B - the right-hand-side matrix (dense matrix) 3486 3487 Output Parameter: 3488 . X - the result matrix (dense matrix) 3489 3490 Notes: 3491 The matrices B and X cannot be the same. I.e., one cannot 3492 call MatMatSolveTranspose(A,X,X). 3493 3494 Notes: 3495 Most users should usually employ the simplified KSP interface for linear solvers 3496 instead of working directly with matrix algebra routines such as this. 3497 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3498 at a time. 3499 3500 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3501 3502 Level: developer 3503 3504 Concepts: matrices^triangular solves 3505 3506 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3507 @*/ 3508 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3509 { 3510 PetscErrorCode ierr; 3511 3512 PetscFunctionBegin; 3513 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3514 PetscValidType(A,1); 3515 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3516 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3517 PetscCheckSameComm(A,1,B,2); 3518 PetscCheckSameComm(A,1,X,3); 3519 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3520 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); 3521 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); 3522 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); 3523 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"); 3524 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3525 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3526 MatCheckPreallocated(A,1); 3527 3528 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3529 if (!A->ops->matsolvetranspose) { 3530 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3531 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3532 } else { 3533 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3534 } 3535 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3536 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3537 PetscFunctionReturn(0); 3538 } 3539 3540 /*@ 3541 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3542 3543 Neighbor-wise Collective on Mat 3544 3545 Input Parameters: 3546 + A - the factored matrix 3547 - Bt - the transpose of right-hand-side matrix 3548 3549 Output Parameter: 3550 . X - the result matrix (dense matrix) 3551 3552 Notes: 3553 Most users should usually employ the simplified KSP interface for linear solvers 3554 instead of working directly with matrix algebra routines such as this. 3555 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3556 at a time. 3557 3558 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(). 3559 3560 Level: developer 3561 3562 Concepts: matrices^triangular solves 3563 3564 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3565 @*/ 3566 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3567 { 3568 PetscErrorCode ierr; 3569 3570 PetscFunctionBegin; 3571 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3572 PetscValidType(A,1); 3573 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3574 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3575 PetscCheckSameComm(A,1,Bt,2); 3576 PetscCheckSameComm(A,1,X,3); 3577 3578 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3579 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); 3580 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); 3581 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"); 3582 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3583 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3584 MatCheckPreallocated(A,1); 3585 3586 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3587 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3588 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3589 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3590 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3591 PetscFunctionReturn(0); 3592 } 3593 3594 /*@ 3595 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3596 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3597 3598 Neighbor-wise Collective on Mat and Vec 3599 3600 Input Parameters: 3601 + mat - the factored matrix 3602 - b - the right-hand-side vector 3603 3604 Output Parameter: 3605 . x - the result vector 3606 3607 Notes: 3608 MatSolve() should be used for most applications, as it performs 3609 a forward solve followed by a backward solve. 3610 3611 The vectors b and x cannot be the same, i.e., one cannot 3612 call MatForwardSolve(A,x,x). 3613 3614 For matrix in seqsbaij format with block size larger than 1, 3615 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3616 MatForwardSolve() solves U^T*D y = b, and 3617 MatBackwardSolve() solves U x = y. 3618 Thus they do not provide a symmetric preconditioner. 3619 3620 Most users should employ the simplified KSP interface for linear solvers 3621 instead of working directly with matrix algebra routines such as this. 3622 See, e.g., KSPCreate(). 3623 3624 Level: developer 3625 3626 Concepts: matrices^forward solves 3627 3628 .seealso: MatSolve(), MatBackwardSolve() 3629 @*/ 3630 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3631 { 3632 PetscErrorCode ierr; 3633 3634 PetscFunctionBegin; 3635 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3636 PetscValidType(mat,1); 3637 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3638 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3639 PetscCheckSameComm(mat,1,b,2); 3640 PetscCheckSameComm(mat,1,x,3); 3641 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3642 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); 3643 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); 3644 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); 3645 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3646 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3647 MatCheckPreallocated(mat,1); 3648 3649 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3650 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3651 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3652 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3653 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3654 PetscFunctionReturn(0); 3655 } 3656 3657 /*@ 3658 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3659 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3660 3661 Neighbor-wise Collective on Mat and Vec 3662 3663 Input Parameters: 3664 + mat - the factored matrix 3665 - b - the right-hand-side vector 3666 3667 Output Parameter: 3668 . x - the result vector 3669 3670 Notes: 3671 MatSolve() should be used for most applications, as it performs 3672 a forward solve followed by a backward solve. 3673 3674 The vectors b and x cannot be the same. I.e., one cannot 3675 call MatBackwardSolve(A,x,x). 3676 3677 For matrix in seqsbaij format with block size larger than 1, 3678 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3679 MatForwardSolve() solves U^T*D y = b, and 3680 MatBackwardSolve() solves U x = y. 3681 Thus they do not provide a symmetric preconditioner. 3682 3683 Most users should employ the simplified KSP interface for linear solvers 3684 instead of working directly with matrix algebra routines such as this. 3685 See, e.g., KSPCreate(). 3686 3687 Level: developer 3688 3689 Concepts: matrices^backward solves 3690 3691 .seealso: MatSolve(), MatForwardSolve() 3692 @*/ 3693 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3694 { 3695 PetscErrorCode ierr; 3696 3697 PetscFunctionBegin; 3698 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3699 PetscValidType(mat,1); 3700 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3701 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3702 PetscCheckSameComm(mat,1,b,2); 3703 PetscCheckSameComm(mat,1,x,3); 3704 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3705 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); 3706 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); 3707 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); 3708 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3709 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3710 MatCheckPreallocated(mat,1); 3711 3712 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3713 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3714 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3715 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3716 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3717 PetscFunctionReturn(0); 3718 } 3719 3720 /*@ 3721 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3722 3723 Neighbor-wise Collective on Mat and Vec 3724 3725 Input Parameters: 3726 + mat - the factored matrix 3727 . b - the right-hand-side vector 3728 - y - the vector to be added to 3729 3730 Output Parameter: 3731 . x - the result vector 3732 3733 Notes: 3734 The vectors b and x cannot be the same. I.e., one cannot 3735 call MatSolveAdd(A,x,y,x). 3736 3737 Most users should employ the simplified KSP interface for linear solvers 3738 instead of working directly with matrix algebra routines such as this. 3739 See, e.g., KSPCreate(). 3740 3741 Level: developer 3742 3743 Concepts: matrices^triangular solves 3744 3745 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3746 @*/ 3747 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3748 { 3749 PetscScalar one = 1.0; 3750 Vec tmp; 3751 PetscErrorCode ierr; 3752 3753 PetscFunctionBegin; 3754 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3755 PetscValidType(mat,1); 3756 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3757 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3758 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3759 PetscCheckSameComm(mat,1,b,2); 3760 PetscCheckSameComm(mat,1,y,2); 3761 PetscCheckSameComm(mat,1,x,3); 3762 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3763 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); 3764 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); 3765 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); 3766 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); 3767 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); 3768 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3769 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3770 MatCheckPreallocated(mat,1); 3771 3772 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3773 if (mat->ops->solveadd) { 3774 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3775 } else { 3776 /* do the solve then the add manually */ 3777 if (x != y) { 3778 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3779 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3780 } else { 3781 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3782 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3783 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3784 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3785 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3786 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3787 } 3788 } 3789 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3790 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3791 PetscFunctionReturn(0); 3792 } 3793 3794 /*@ 3795 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3796 3797 Neighbor-wise Collective on Mat and Vec 3798 3799 Input Parameters: 3800 + mat - the factored matrix 3801 - b - the right-hand-side vector 3802 3803 Output Parameter: 3804 . x - the result vector 3805 3806 Notes: 3807 The vectors b and x cannot be the same. I.e., one cannot 3808 call MatSolveTranspose(A,x,x). 3809 3810 Most users should employ the simplified KSP interface for linear solvers 3811 instead of working directly with matrix algebra routines such as this. 3812 See, e.g., KSPCreate(). 3813 3814 Level: developer 3815 3816 Concepts: matrices^triangular solves 3817 3818 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3819 @*/ 3820 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3821 { 3822 PetscErrorCode ierr; 3823 3824 PetscFunctionBegin; 3825 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3826 PetscValidType(mat,1); 3827 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3828 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3829 PetscCheckSameComm(mat,1,b,2); 3830 PetscCheckSameComm(mat,1,x,3); 3831 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3832 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); 3833 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); 3834 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3835 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3836 MatCheckPreallocated(mat,1); 3837 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3838 if (mat->factorerrortype) { 3839 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3840 ierr = VecSetInf(x);CHKERRQ(ierr); 3841 } else { 3842 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3843 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3844 } 3845 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3846 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3847 PetscFunctionReturn(0); 3848 } 3849 3850 /*@ 3851 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3852 factored matrix. 3853 3854 Neighbor-wise Collective on Mat and Vec 3855 3856 Input Parameters: 3857 + mat - the factored matrix 3858 . b - the right-hand-side vector 3859 - y - the vector to be added to 3860 3861 Output Parameter: 3862 . x - the result vector 3863 3864 Notes: 3865 The vectors b and x cannot be the same. I.e., one cannot 3866 call MatSolveTransposeAdd(A,x,y,x). 3867 3868 Most users should employ the simplified KSP interface for linear solvers 3869 instead of working directly with matrix algebra routines such as this. 3870 See, e.g., KSPCreate(). 3871 3872 Level: developer 3873 3874 Concepts: matrices^triangular solves 3875 3876 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3877 @*/ 3878 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3879 { 3880 PetscScalar one = 1.0; 3881 PetscErrorCode ierr; 3882 Vec tmp; 3883 3884 PetscFunctionBegin; 3885 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3886 PetscValidType(mat,1); 3887 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3888 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3889 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3890 PetscCheckSameComm(mat,1,b,2); 3891 PetscCheckSameComm(mat,1,y,3); 3892 PetscCheckSameComm(mat,1,x,4); 3893 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3894 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); 3895 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); 3896 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); 3897 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); 3898 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3899 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3900 MatCheckPreallocated(mat,1); 3901 3902 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3903 if (mat->ops->solvetransposeadd) { 3904 if (mat->factorerrortype) { 3905 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3906 ierr = VecSetInf(x);CHKERRQ(ierr); 3907 } else { 3908 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3909 } 3910 } else { 3911 /* do the solve then the add manually */ 3912 if (x != y) { 3913 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3914 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3915 } else { 3916 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3917 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3918 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3919 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3920 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3921 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3922 } 3923 } 3924 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3925 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3926 PetscFunctionReturn(0); 3927 } 3928 /* ----------------------------------------------------------------*/ 3929 3930 /*@ 3931 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3932 3933 Neighbor-wise Collective on Mat and Vec 3934 3935 Input Parameters: 3936 + mat - the matrix 3937 . b - the right hand side 3938 . omega - the relaxation factor 3939 . flag - flag indicating the type of SOR (see below) 3940 . shift - diagonal shift 3941 . its - the number of iterations 3942 - lits - the number of local iterations 3943 3944 Output Parameters: 3945 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3946 3947 SOR Flags: 3948 . SOR_FORWARD_SWEEP - forward SOR 3949 . SOR_BACKWARD_SWEEP - backward SOR 3950 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3951 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3952 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3953 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3954 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3955 upper/lower triangular part of matrix to 3956 vector (with omega) 3957 . SOR_ZERO_INITIAL_GUESS - zero initial guess 3958 3959 Notes: 3960 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3961 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3962 on each processor. 3963 3964 Application programmers will not generally use MatSOR() directly, 3965 but instead will employ the KSP/PC interface. 3966 3967 Notes: 3968 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3969 3970 Notes for Advanced Users: 3971 The flags are implemented as bitwise inclusive or operations. 3972 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3973 to specify a zero initial guess for SSOR. 3974 3975 Most users should employ the simplified KSP interface for linear solvers 3976 instead of working directly with matrix algebra routines such as this. 3977 See, e.g., KSPCreate(). 3978 3979 Vectors x and b CANNOT be the same 3980 3981 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3982 3983 Level: developer 3984 3985 Concepts: matrices^relaxation 3986 Concepts: matrices^SOR 3987 Concepts: matrices^Gauss-Seidel 3988 3989 @*/ 3990 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3991 { 3992 PetscErrorCode ierr; 3993 3994 PetscFunctionBegin; 3995 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3996 PetscValidType(mat,1); 3997 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3998 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3999 PetscCheckSameComm(mat,1,b,2); 4000 PetscCheckSameComm(mat,1,x,8); 4001 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4002 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4003 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4004 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); 4005 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); 4006 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); 4007 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 4008 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 4009 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4010 4011 MatCheckPreallocated(mat,1); 4012 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4013 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 4014 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4015 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 4016 PetscFunctionReturn(0); 4017 } 4018 4019 /* 4020 Default matrix copy routine. 4021 */ 4022 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4023 { 4024 PetscErrorCode ierr; 4025 PetscInt i,rstart = 0,rend = 0,nz; 4026 const PetscInt *cwork; 4027 const PetscScalar *vwork; 4028 4029 PetscFunctionBegin; 4030 if (B->assembled) { 4031 ierr = MatZeroEntries(B);CHKERRQ(ierr); 4032 } 4033 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 4034 for (i=rstart; i<rend; i++) { 4035 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4036 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 4037 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4038 } 4039 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4040 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4041 PetscFunctionReturn(0); 4042 } 4043 4044 /*@ 4045 MatCopy - Copys a matrix to another matrix. 4046 4047 Collective on Mat 4048 4049 Input Parameters: 4050 + A - the matrix 4051 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4052 4053 Output Parameter: 4054 . B - where the copy is put 4055 4056 Notes: 4057 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 4058 same nonzero pattern or the routine will crash. 4059 4060 MatCopy() copies the matrix entries of a matrix to another existing 4061 matrix (after first zeroing the second matrix). A related routine is 4062 MatConvert(), which first creates a new matrix and then copies the data. 4063 4064 Level: intermediate 4065 4066 Concepts: matrices^copying 4067 4068 .seealso: MatConvert(), MatDuplicate() 4069 4070 @*/ 4071 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4072 { 4073 PetscErrorCode ierr; 4074 PetscInt i; 4075 4076 PetscFunctionBegin; 4077 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4078 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4079 PetscValidType(A,1); 4080 PetscValidType(B,2); 4081 PetscCheckSameComm(A,1,B,2); 4082 MatCheckPreallocated(B,2); 4083 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4084 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4085 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); 4086 MatCheckPreallocated(A,1); 4087 if (A == B) PetscFunctionReturn(0); 4088 4089 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4090 if (A->ops->copy) { 4091 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4092 } else { /* generic conversion */ 4093 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4094 } 4095 4096 B->stencil.dim = A->stencil.dim; 4097 B->stencil.noc = A->stencil.noc; 4098 for (i=0; i<=A->stencil.dim; i++) { 4099 B->stencil.dims[i] = A->stencil.dims[i]; 4100 B->stencil.starts[i] = A->stencil.starts[i]; 4101 } 4102 4103 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4104 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4105 PetscFunctionReturn(0); 4106 } 4107 4108 /*@C 4109 MatConvert - Converts a matrix to another matrix, either of the same 4110 or different type. 4111 4112 Collective on Mat 4113 4114 Input Parameters: 4115 + mat - the matrix 4116 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4117 same type as the original matrix. 4118 - reuse - denotes if the destination matrix is to be created or reused. 4119 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 4120 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). 4121 4122 Output Parameter: 4123 . M - pointer to place new matrix 4124 4125 Notes: 4126 MatConvert() first creates a new matrix and then copies the data from 4127 the first matrix. A related routine is MatCopy(), which copies the matrix 4128 entries of one matrix to another already existing matrix context. 4129 4130 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4131 the MPI communicator of the generated matrix is always the same as the communicator 4132 of the input matrix. 4133 4134 Level: intermediate 4135 4136 Concepts: matrices^converting between storage formats 4137 4138 .seealso: MatCopy(), MatDuplicate() 4139 @*/ 4140 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4141 { 4142 PetscErrorCode ierr; 4143 PetscBool sametype,issame,flg; 4144 char convname[256],mtype[256]; 4145 Mat B; 4146 4147 PetscFunctionBegin; 4148 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4149 PetscValidType(mat,1); 4150 PetscValidPointer(M,3); 4151 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4152 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4153 MatCheckPreallocated(mat,1); 4154 4155 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4156 if (flg) { 4157 newtype = mtype; 4158 } 4159 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4160 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4161 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4162 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"); 4163 4164 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 4165 4166 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4167 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4168 } else { 4169 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4170 const char *prefix[3] = {"seq","mpi",""}; 4171 PetscInt i; 4172 /* 4173 Order of precedence: 4174 0) See if newtype is a superclass of the current matrix. 4175 1) See if a specialized converter is known to the current matrix. 4176 2) See if a specialized converter is known to the desired matrix class. 4177 3) See if a good general converter is registered for the desired class 4178 (as of 6/27/03 only MATMPIADJ falls into this category). 4179 4) See if a good general converter is known for the current matrix. 4180 5) Use a really basic converter. 4181 */ 4182 4183 /* 0) See if newtype is a superclass of the current matrix. 4184 i.e mat is mpiaij and newtype is aij */ 4185 for (i=0; i<2; i++) { 4186 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4187 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4188 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4189 if (flg) { 4190 if (reuse == MAT_INPLACE_MATRIX) { 4191 PetscFunctionReturn(0); 4192 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4193 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4194 PetscFunctionReturn(0); 4195 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4196 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4197 PetscFunctionReturn(0); 4198 } 4199 } 4200 } 4201 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4202 for (i=0; i<3; i++) { 4203 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4204 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4205 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4206 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4207 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4208 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4209 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4210 if (conv) goto foundconv; 4211 } 4212 4213 /* 2) See if a specialized converter is known to the desired matrix class. */ 4214 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4215 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4216 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4217 for (i=0; i<3; i++) { 4218 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4219 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4220 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4221 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4222 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4223 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4224 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4225 if (conv) { 4226 ierr = MatDestroy(&B);CHKERRQ(ierr); 4227 goto foundconv; 4228 } 4229 } 4230 4231 /* 3) See if a good general converter is registered for the desired class */ 4232 conv = B->ops->convertfrom; 4233 ierr = MatDestroy(&B);CHKERRQ(ierr); 4234 if (conv) goto foundconv; 4235 4236 /* 4) See if a good general converter is known for the current matrix */ 4237 if (mat->ops->convert) { 4238 conv = mat->ops->convert; 4239 } 4240 if (conv) goto foundconv; 4241 4242 /* 5) Use a really basic converter. */ 4243 conv = MatConvert_Basic; 4244 4245 foundconv: 4246 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4247 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4248 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4249 /* the block sizes must be same if the mappings are copied over */ 4250 (*M)->rmap->bs = mat->rmap->bs; 4251 (*M)->cmap->bs = mat->cmap->bs; 4252 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4253 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4254 (*M)->rmap->mapping = mat->rmap->mapping; 4255 (*M)->cmap->mapping = mat->cmap->mapping; 4256 } 4257 (*M)->stencil.dim = mat->stencil.dim; 4258 (*M)->stencil.noc = mat->stencil.noc; 4259 for (i=0; i<=mat->stencil.dim; i++) { 4260 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4261 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4262 } 4263 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4264 } 4265 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4266 4267 /* Copy Mat options */ 4268 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4269 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4270 PetscFunctionReturn(0); 4271 } 4272 4273 /*@C 4274 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4275 4276 Not Collective 4277 4278 Input Parameter: 4279 . mat - the matrix, must be a factored matrix 4280 4281 Output Parameter: 4282 . type - the string name of the package (do not free this string) 4283 4284 Notes: 4285 In Fortran you pass in a empty string and the package name will be copied into it. 4286 (Make sure the string is long enough) 4287 4288 Level: intermediate 4289 4290 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4291 @*/ 4292 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4293 { 4294 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4295 4296 PetscFunctionBegin; 4297 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4298 PetscValidType(mat,1); 4299 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4300 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4301 if (!conv) { 4302 *type = MATSOLVERPETSC; 4303 } else { 4304 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4305 } 4306 PetscFunctionReturn(0); 4307 } 4308 4309 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4310 struct _MatSolverTypeForSpecifcType { 4311 MatType mtype; 4312 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4313 MatSolverTypeForSpecifcType next; 4314 }; 4315 4316 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4317 struct _MatSolverTypeHolder { 4318 char *name; 4319 MatSolverTypeForSpecifcType handlers; 4320 MatSolverTypeHolder next; 4321 }; 4322 4323 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4324 4325 /*@C 4326 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4327 4328 Input Parameters: 4329 + package - name of the package, for example petsc or superlu 4330 . mtype - the matrix type that works with this package 4331 . ftype - the type of factorization supported by the package 4332 - getfactor - routine that will create the factored matrix ready to be used 4333 4334 Level: intermediate 4335 4336 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4337 @*/ 4338 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4339 { 4340 PetscErrorCode ierr; 4341 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4342 PetscBool flg; 4343 MatSolverTypeForSpecifcType inext,iprev = NULL; 4344 4345 PetscFunctionBegin; 4346 ierr = MatInitializePackage();CHKERRQ(ierr); 4347 if (!next) { 4348 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4349 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4350 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4351 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4352 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4353 PetscFunctionReturn(0); 4354 } 4355 while (next) { 4356 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4357 if (flg) { 4358 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4359 inext = next->handlers; 4360 while (inext) { 4361 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4362 if (flg) { 4363 inext->getfactor[(int)ftype-1] = getfactor; 4364 PetscFunctionReturn(0); 4365 } 4366 iprev = inext; 4367 inext = inext->next; 4368 } 4369 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4370 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4371 iprev->next->getfactor[(int)ftype-1] = getfactor; 4372 PetscFunctionReturn(0); 4373 } 4374 prev = next; 4375 next = next->next; 4376 } 4377 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4378 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4379 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4380 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4381 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4382 PetscFunctionReturn(0); 4383 } 4384 4385 /*@C 4386 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4387 4388 Input Parameters: 4389 + package - name of the package, for example petsc or superlu 4390 . ftype - the type of factorization supported by the package 4391 - mtype - the matrix type that works with this package 4392 4393 Output Parameters: 4394 + foundpackage - PETSC_TRUE if the package was registered 4395 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4396 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4397 4398 Level: intermediate 4399 4400 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4401 @*/ 4402 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4403 { 4404 PetscErrorCode ierr; 4405 MatSolverTypeHolder next = MatSolverTypeHolders; 4406 PetscBool flg; 4407 MatSolverTypeForSpecifcType inext; 4408 4409 PetscFunctionBegin; 4410 if (foundpackage) *foundpackage = PETSC_FALSE; 4411 if (foundmtype) *foundmtype = PETSC_FALSE; 4412 if (getfactor) *getfactor = NULL; 4413 4414 if (package) { 4415 while (next) { 4416 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4417 if (flg) { 4418 if (foundpackage) *foundpackage = PETSC_TRUE; 4419 inext = next->handlers; 4420 while (inext) { 4421 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4422 if (flg) { 4423 if (foundmtype) *foundmtype = PETSC_TRUE; 4424 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4425 PetscFunctionReturn(0); 4426 } 4427 inext = inext->next; 4428 } 4429 } 4430 next = next->next; 4431 } 4432 } else { 4433 while (next) { 4434 inext = next->handlers; 4435 while (inext) { 4436 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4437 if (flg && inext->getfactor[(int)ftype-1]) { 4438 if (foundpackage) *foundpackage = PETSC_TRUE; 4439 if (foundmtype) *foundmtype = PETSC_TRUE; 4440 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4441 PetscFunctionReturn(0); 4442 } 4443 inext = inext->next; 4444 } 4445 next = next->next; 4446 } 4447 } 4448 PetscFunctionReturn(0); 4449 } 4450 4451 PetscErrorCode MatSolverTypeDestroy(void) 4452 { 4453 PetscErrorCode ierr; 4454 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4455 MatSolverTypeForSpecifcType inext,iprev; 4456 4457 PetscFunctionBegin; 4458 while (next) { 4459 ierr = PetscFree(next->name);CHKERRQ(ierr); 4460 inext = next->handlers; 4461 while (inext) { 4462 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4463 iprev = inext; 4464 inext = inext->next; 4465 ierr = PetscFree(iprev);CHKERRQ(ierr); 4466 } 4467 prev = next; 4468 next = next->next; 4469 ierr = PetscFree(prev);CHKERRQ(ierr); 4470 } 4471 MatSolverTypeHolders = NULL; 4472 PetscFunctionReturn(0); 4473 } 4474 4475 /*@C 4476 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4477 4478 Collective on Mat 4479 4480 Input Parameters: 4481 + mat - the matrix 4482 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4483 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4484 4485 Output Parameters: 4486 . f - the factor matrix used with MatXXFactorSymbolic() calls 4487 4488 Notes: 4489 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4490 such as pastix, superlu, mumps etc. 4491 4492 PETSc must have been ./configure to use the external solver, using the option --download-package 4493 4494 Level: intermediate 4495 4496 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4497 @*/ 4498 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4499 { 4500 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4501 PetscBool foundpackage,foundmtype; 4502 4503 PetscFunctionBegin; 4504 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4505 PetscValidType(mat,1); 4506 4507 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4508 MatCheckPreallocated(mat,1); 4509 4510 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4511 if (!foundpackage) { 4512 if (type) { 4513 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4514 } else { 4515 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4516 } 4517 } 4518 4519 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4520 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); 4521 4522 #if defined(PETSC_USE_COMPLEX) 4523 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"); 4524 #endif 4525 4526 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4527 PetscFunctionReturn(0); 4528 } 4529 4530 /*@C 4531 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4532 4533 Not Collective 4534 4535 Input Parameters: 4536 + mat - the matrix 4537 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4538 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4539 4540 Output Parameter: 4541 . flg - PETSC_TRUE if the factorization is available 4542 4543 Notes: 4544 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4545 such as pastix, superlu, mumps etc. 4546 4547 PETSc must have been ./configure to use the external solver, using the option --download-package 4548 4549 Level: intermediate 4550 4551 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4552 @*/ 4553 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4554 { 4555 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4556 4557 PetscFunctionBegin; 4558 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4559 PetscValidType(mat,1); 4560 4561 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4562 MatCheckPreallocated(mat,1); 4563 4564 *flg = PETSC_FALSE; 4565 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4566 if (gconv) { 4567 *flg = PETSC_TRUE; 4568 } 4569 PetscFunctionReturn(0); 4570 } 4571 4572 #include <petscdmtypes.h> 4573 4574 /*@ 4575 MatDuplicate - Duplicates a matrix including the non-zero structure. 4576 4577 Collective on Mat 4578 4579 Input Parameters: 4580 + mat - the matrix 4581 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4582 See the manual page for MatDuplicateOption for an explanation of these options. 4583 4584 Output Parameter: 4585 . M - pointer to place new matrix 4586 4587 Level: intermediate 4588 4589 Concepts: matrices^duplicating 4590 4591 Notes: 4592 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4593 When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation. 4594 4595 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4596 @*/ 4597 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4598 { 4599 PetscErrorCode ierr; 4600 Mat B; 4601 PetscInt i; 4602 DM dm; 4603 void (*viewf)(void); 4604 4605 PetscFunctionBegin; 4606 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4607 PetscValidType(mat,1); 4608 PetscValidPointer(M,3); 4609 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4610 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4611 MatCheckPreallocated(mat,1); 4612 4613 *M = 0; 4614 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4615 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4616 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4617 B = *M; 4618 4619 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4620 if (viewf) { 4621 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4622 } 4623 4624 B->stencil.dim = mat->stencil.dim; 4625 B->stencil.noc = mat->stencil.noc; 4626 for (i=0; i<=mat->stencil.dim; i++) { 4627 B->stencil.dims[i] = mat->stencil.dims[i]; 4628 B->stencil.starts[i] = mat->stencil.starts[i]; 4629 } 4630 4631 B->nooffproczerorows = mat->nooffproczerorows; 4632 B->nooffprocentries = mat->nooffprocentries; 4633 4634 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4635 if (dm) { 4636 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4637 } 4638 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4639 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4640 PetscFunctionReturn(0); 4641 } 4642 4643 /*@ 4644 MatGetDiagonal - Gets the diagonal of a matrix. 4645 4646 Logically Collective on Mat and Vec 4647 4648 Input Parameters: 4649 + mat - the matrix 4650 - v - the vector for storing the diagonal 4651 4652 Output Parameter: 4653 . v - the diagonal of the matrix 4654 4655 Level: intermediate 4656 4657 Note: 4658 Currently only correct in parallel for square matrices. 4659 4660 Concepts: matrices^accessing diagonals 4661 4662 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4663 @*/ 4664 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4665 { 4666 PetscErrorCode ierr; 4667 4668 PetscFunctionBegin; 4669 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4670 PetscValidType(mat,1); 4671 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4672 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4673 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4674 MatCheckPreallocated(mat,1); 4675 4676 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4677 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4678 PetscFunctionReturn(0); 4679 } 4680 4681 /*@C 4682 MatGetRowMin - Gets the minimum value (of the real part) of each 4683 row of the matrix 4684 4685 Logically Collective on Mat and Vec 4686 4687 Input Parameters: 4688 . mat - the matrix 4689 4690 Output Parameter: 4691 + v - the vector for storing the maximums 4692 - idx - the indices of the column found for each row (optional) 4693 4694 Level: intermediate 4695 4696 Notes: 4697 The result of this call are the same as if one converted the matrix to dense format 4698 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4699 4700 This code is only implemented for a couple of matrix formats. 4701 4702 Concepts: matrices^getting row maximums 4703 4704 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4705 MatGetRowMax() 4706 @*/ 4707 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4708 { 4709 PetscErrorCode ierr; 4710 4711 PetscFunctionBegin; 4712 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4713 PetscValidType(mat,1); 4714 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4715 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4716 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4717 MatCheckPreallocated(mat,1); 4718 4719 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4720 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4721 PetscFunctionReturn(0); 4722 } 4723 4724 /*@C 4725 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4726 row of the matrix 4727 4728 Logically Collective on Mat and Vec 4729 4730 Input Parameters: 4731 . mat - the matrix 4732 4733 Output Parameter: 4734 + v - the vector for storing the minimums 4735 - idx - the indices of the column found for each row (or NULL if not needed) 4736 4737 Level: intermediate 4738 4739 Notes: 4740 if a row is completely empty or has only 0.0 values then the idx[] value for that 4741 row is 0 (the first column). 4742 4743 This code is only implemented for a couple of matrix formats. 4744 4745 Concepts: matrices^getting row maximums 4746 4747 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4748 @*/ 4749 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4750 { 4751 PetscErrorCode ierr; 4752 4753 PetscFunctionBegin; 4754 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4755 PetscValidType(mat,1); 4756 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4757 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4758 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4759 MatCheckPreallocated(mat,1); 4760 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4761 4762 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4763 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4764 PetscFunctionReturn(0); 4765 } 4766 4767 /*@C 4768 MatGetRowMax - Gets the maximum value (of the real part) of each 4769 row of the matrix 4770 4771 Logically Collective on Mat and Vec 4772 4773 Input Parameters: 4774 . mat - the matrix 4775 4776 Output Parameter: 4777 + v - the vector for storing the maximums 4778 - idx - the indices of the column found for each row (optional) 4779 4780 Level: intermediate 4781 4782 Notes: 4783 The result of this call are the same as if one converted the matrix to dense format 4784 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4785 4786 This code is only implemented for a couple of matrix formats. 4787 4788 Concepts: matrices^getting row maximums 4789 4790 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4791 @*/ 4792 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4793 { 4794 PetscErrorCode ierr; 4795 4796 PetscFunctionBegin; 4797 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4798 PetscValidType(mat,1); 4799 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4800 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4801 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4802 MatCheckPreallocated(mat,1); 4803 4804 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4805 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4806 PetscFunctionReturn(0); 4807 } 4808 4809 /*@C 4810 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4811 row of the matrix 4812 4813 Logically Collective on Mat and Vec 4814 4815 Input Parameters: 4816 . mat - the matrix 4817 4818 Output Parameter: 4819 + v - the vector for storing the maximums 4820 - idx - the indices of the column found for each row (or NULL if not needed) 4821 4822 Level: intermediate 4823 4824 Notes: 4825 if a row is completely empty or has only 0.0 values then the idx[] value for that 4826 row is 0 (the first column). 4827 4828 This code is only implemented for a couple of matrix formats. 4829 4830 Concepts: matrices^getting row maximums 4831 4832 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4833 @*/ 4834 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4835 { 4836 PetscErrorCode ierr; 4837 4838 PetscFunctionBegin; 4839 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4840 PetscValidType(mat,1); 4841 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4842 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4843 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4844 MatCheckPreallocated(mat,1); 4845 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4846 4847 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4848 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4849 PetscFunctionReturn(0); 4850 } 4851 4852 /*@ 4853 MatGetRowSum - Gets the sum of each row of the matrix 4854 4855 Logically or Neighborhood Collective on Mat and Vec 4856 4857 Input Parameters: 4858 . mat - the matrix 4859 4860 Output Parameter: 4861 . v - the vector for storing the sum of rows 4862 4863 Level: intermediate 4864 4865 Notes: 4866 This code is slow since it is not currently specialized for different formats 4867 4868 Concepts: matrices^getting row sums 4869 4870 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4871 @*/ 4872 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4873 { 4874 Vec ones; 4875 PetscErrorCode ierr; 4876 4877 PetscFunctionBegin; 4878 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4879 PetscValidType(mat,1); 4880 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4881 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4882 MatCheckPreallocated(mat,1); 4883 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4884 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4885 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4886 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4887 PetscFunctionReturn(0); 4888 } 4889 4890 /*@ 4891 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4892 4893 Collective on Mat 4894 4895 Input Parameter: 4896 + mat - the matrix to transpose 4897 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4898 4899 Output Parameters: 4900 . B - the transpose 4901 4902 Notes: 4903 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4904 4905 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4906 4907 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4908 4909 Level: intermediate 4910 4911 Concepts: matrices^transposing 4912 4913 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4914 @*/ 4915 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4916 { 4917 PetscErrorCode ierr; 4918 4919 PetscFunctionBegin; 4920 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4921 PetscValidType(mat,1); 4922 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4923 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4924 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4925 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4926 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4927 MatCheckPreallocated(mat,1); 4928 4929 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4930 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4931 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4932 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4933 PetscFunctionReturn(0); 4934 } 4935 4936 /*@ 4937 MatIsTranspose - Test whether a matrix is another one's transpose, 4938 or its own, in which case it tests symmetry. 4939 4940 Collective on Mat 4941 4942 Input Parameter: 4943 + A - the matrix to test 4944 - B - the matrix to test against, this can equal the first parameter 4945 4946 Output Parameters: 4947 . flg - the result 4948 4949 Notes: 4950 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4951 has a running time of the order of the number of nonzeros; the parallel 4952 test involves parallel copies of the block-offdiagonal parts of the matrix. 4953 4954 Level: intermediate 4955 4956 Concepts: matrices^transposing, matrix^symmetry 4957 4958 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4959 @*/ 4960 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4961 { 4962 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4963 4964 PetscFunctionBegin; 4965 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4966 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4967 PetscValidPointer(flg,3); 4968 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4969 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4970 *flg = PETSC_FALSE; 4971 if (f && g) { 4972 if (f == g) { 4973 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4974 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4975 } else { 4976 MatType mattype; 4977 if (!f) { 4978 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4979 } else { 4980 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4981 } 4982 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4983 } 4984 PetscFunctionReturn(0); 4985 } 4986 4987 /*@ 4988 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4989 4990 Collective on Mat 4991 4992 Input Parameter: 4993 + mat - the matrix to transpose and complex conjugate 4994 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4995 4996 Output Parameters: 4997 . B - the Hermitian 4998 4999 Level: intermediate 5000 5001 Concepts: matrices^transposing, complex conjugatex 5002 5003 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 5004 @*/ 5005 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5006 { 5007 PetscErrorCode ierr; 5008 5009 PetscFunctionBegin; 5010 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 5011 #if defined(PETSC_USE_COMPLEX) 5012 ierr = MatConjugate(*B);CHKERRQ(ierr); 5013 #endif 5014 PetscFunctionReturn(0); 5015 } 5016 5017 /*@ 5018 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5019 5020 Collective on Mat 5021 5022 Input Parameter: 5023 + A - the matrix to test 5024 - B - the matrix to test against, this can equal the first parameter 5025 5026 Output Parameters: 5027 . flg - the result 5028 5029 Notes: 5030 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5031 has a running time of the order of the number of nonzeros; the parallel 5032 test involves parallel copies of the block-offdiagonal parts of the matrix. 5033 5034 Level: intermediate 5035 5036 Concepts: matrices^transposing, matrix^symmetry 5037 5038 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 5039 @*/ 5040 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5041 { 5042 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5043 5044 PetscFunctionBegin; 5045 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5046 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5047 PetscValidPointer(flg,3); 5048 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 5049 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 5050 if (f && g) { 5051 if (f==g) { 5052 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5053 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5054 } 5055 PetscFunctionReturn(0); 5056 } 5057 5058 /*@ 5059 MatPermute - Creates a new matrix with rows and columns permuted from the 5060 original. 5061 5062 Collective on Mat 5063 5064 Input Parameters: 5065 + mat - the matrix to permute 5066 . row - row permutation, each processor supplies only the permutation for its rows 5067 - col - column permutation, each processor supplies only the permutation for its columns 5068 5069 Output Parameters: 5070 . B - the permuted matrix 5071 5072 Level: advanced 5073 5074 Note: 5075 The index sets map from row/col of permuted matrix to row/col of original matrix. 5076 The index sets should be on the same communicator as Mat and have the same local sizes. 5077 5078 Concepts: matrices^permuting 5079 5080 .seealso: MatGetOrdering(), ISAllGather() 5081 5082 @*/ 5083 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5084 { 5085 PetscErrorCode ierr; 5086 5087 PetscFunctionBegin; 5088 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5089 PetscValidType(mat,1); 5090 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5091 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5092 PetscValidPointer(B,4); 5093 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5094 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5095 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5096 MatCheckPreallocated(mat,1); 5097 5098 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5099 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5100 PetscFunctionReturn(0); 5101 } 5102 5103 /*@ 5104 MatEqual - Compares two matrices. 5105 5106 Collective on Mat 5107 5108 Input Parameters: 5109 + A - the first matrix 5110 - B - the second matrix 5111 5112 Output Parameter: 5113 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5114 5115 Level: intermediate 5116 5117 Concepts: matrices^equality between 5118 @*/ 5119 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5120 { 5121 PetscErrorCode ierr; 5122 5123 PetscFunctionBegin; 5124 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5125 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5126 PetscValidType(A,1); 5127 PetscValidType(B,2); 5128 PetscValidIntPointer(flg,3); 5129 PetscCheckSameComm(A,1,B,2); 5130 MatCheckPreallocated(B,2); 5131 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5132 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5133 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); 5134 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5135 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5136 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); 5137 MatCheckPreallocated(A,1); 5138 5139 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5140 PetscFunctionReturn(0); 5141 } 5142 5143 /*@ 5144 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5145 matrices that are stored as vectors. Either of the two scaling 5146 matrices can be NULL. 5147 5148 Collective on Mat 5149 5150 Input Parameters: 5151 + mat - the matrix to be scaled 5152 . l - the left scaling vector (or NULL) 5153 - r - the right scaling vector (or NULL) 5154 5155 Notes: 5156 MatDiagonalScale() computes A = LAR, where 5157 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5158 The L scales the rows of the matrix, the R scales the columns of the matrix. 5159 5160 Level: intermediate 5161 5162 Concepts: matrices^diagonal scaling 5163 Concepts: diagonal scaling of matrices 5164 5165 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5166 @*/ 5167 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5168 { 5169 PetscErrorCode ierr; 5170 5171 PetscFunctionBegin; 5172 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5173 PetscValidType(mat,1); 5174 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5175 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5176 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5177 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5178 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5179 MatCheckPreallocated(mat,1); 5180 5181 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5182 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5183 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5184 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5185 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5186 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5187 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5188 } 5189 #endif 5190 PetscFunctionReturn(0); 5191 } 5192 5193 /*@ 5194 MatScale - Scales all elements of a matrix by a given number. 5195 5196 Logically Collective on Mat 5197 5198 Input Parameters: 5199 + mat - the matrix to be scaled 5200 - a - the scaling value 5201 5202 Output Parameter: 5203 . mat - the scaled matrix 5204 5205 Level: intermediate 5206 5207 Concepts: matrices^scaling all entries 5208 5209 .seealso: MatDiagonalScale() 5210 @*/ 5211 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5212 { 5213 PetscErrorCode ierr; 5214 5215 PetscFunctionBegin; 5216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5217 PetscValidType(mat,1); 5218 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5219 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5220 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5221 PetscValidLogicalCollectiveScalar(mat,a,2); 5222 MatCheckPreallocated(mat,1); 5223 5224 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5225 if (a != (PetscScalar)1.0) { 5226 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5227 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5228 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5229 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5230 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5231 } 5232 #endif 5233 } 5234 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5235 PetscFunctionReturn(0); 5236 } 5237 5238 /*@ 5239 MatNorm - Calculates various norms of a matrix. 5240 5241 Collective on Mat 5242 5243 Input Parameters: 5244 + mat - the matrix 5245 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5246 5247 Output Parameters: 5248 . nrm - the resulting norm 5249 5250 Level: intermediate 5251 5252 Concepts: matrices^norm 5253 Concepts: norm^of matrix 5254 @*/ 5255 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5256 { 5257 PetscErrorCode ierr; 5258 5259 PetscFunctionBegin; 5260 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5261 PetscValidType(mat,1); 5262 PetscValidScalarPointer(nrm,3); 5263 5264 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5265 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5266 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5267 MatCheckPreallocated(mat,1); 5268 5269 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5270 PetscFunctionReturn(0); 5271 } 5272 5273 /* 5274 This variable is used to prevent counting of MatAssemblyBegin() that 5275 are called from within a MatAssemblyEnd(). 5276 */ 5277 static PetscInt MatAssemblyEnd_InUse = 0; 5278 /*@ 5279 MatAssemblyBegin - Begins assembling the matrix. This routine should 5280 be called after completing all calls to MatSetValues(). 5281 5282 Collective on Mat 5283 5284 Input Parameters: 5285 + mat - the matrix 5286 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5287 5288 Notes: 5289 MatSetValues() generally caches the values. The matrix is ready to 5290 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5291 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5292 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5293 using the matrix. 5294 5295 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5296 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 5297 a global collective operation requring all processes that share the matrix. 5298 5299 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5300 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5301 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5302 5303 Level: beginner 5304 5305 Concepts: matrices^assembling 5306 5307 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5308 @*/ 5309 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5310 { 5311 PetscErrorCode ierr; 5312 5313 PetscFunctionBegin; 5314 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5315 PetscValidType(mat,1); 5316 MatCheckPreallocated(mat,1); 5317 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5318 if (mat->assembled) { 5319 mat->was_assembled = PETSC_TRUE; 5320 mat->assembled = PETSC_FALSE; 5321 } 5322 if (!MatAssemblyEnd_InUse) { 5323 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5324 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5325 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5326 } else if (mat->ops->assemblybegin) { 5327 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5328 } 5329 PetscFunctionReturn(0); 5330 } 5331 5332 /*@ 5333 MatAssembled - Indicates if a matrix has been assembled and is ready for 5334 use; for example, in matrix-vector product. 5335 5336 Not Collective 5337 5338 Input Parameter: 5339 . mat - the matrix 5340 5341 Output Parameter: 5342 . assembled - PETSC_TRUE or PETSC_FALSE 5343 5344 Level: advanced 5345 5346 Concepts: matrices^assembled? 5347 5348 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5349 @*/ 5350 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5351 { 5352 PetscFunctionBegin; 5353 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5354 PetscValidPointer(assembled,2); 5355 *assembled = mat->assembled; 5356 PetscFunctionReturn(0); 5357 } 5358 5359 /*@ 5360 MatAssemblyEnd - Completes assembling the matrix. This routine should 5361 be called after MatAssemblyBegin(). 5362 5363 Collective on Mat 5364 5365 Input Parameters: 5366 + mat - the matrix 5367 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5368 5369 Options Database Keys: 5370 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5371 . -mat_view ::ascii_info_detail - Prints more detailed info 5372 . -mat_view - Prints matrix in ASCII format 5373 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5374 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5375 . -display <name> - Sets display name (default is host) 5376 . -draw_pause <sec> - Sets number of seconds to pause after display 5377 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5378 . -viewer_socket_machine <machine> - Machine to use for socket 5379 . -viewer_socket_port <port> - Port number to use for socket 5380 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5381 5382 Notes: 5383 MatSetValues() generally caches the values. The matrix is ready to 5384 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5385 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5386 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5387 using the matrix. 5388 5389 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5390 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5391 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5392 5393 Level: beginner 5394 5395 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5396 @*/ 5397 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5398 { 5399 PetscErrorCode ierr; 5400 static PetscInt inassm = 0; 5401 PetscBool flg = PETSC_FALSE; 5402 5403 PetscFunctionBegin; 5404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5405 PetscValidType(mat,1); 5406 5407 inassm++; 5408 MatAssemblyEnd_InUse++; 5409 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5410 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5411 if (mat->ops->assemblyend) { 5412 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5413 } 5414 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5415 } else if (mat->ops->assemblyend) { 5416 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5417 } 5418 5419 /* Flush assembly is not a true assembly */ 5420 if (type != MAT_FLUSH_ASSEMBLY) { 5421 mat->assembled = PETSC_TRUE; mat->num_ass++; 5422 } 5423 mat->insertmode = NOT_SET_VALUES; 5424 MatAssemblyEnd_InUse--; 5425 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5426 if (!mat->symmetric_eternal) { 5427 mat->symmetric_set = PETSC_FALSE; 5428 mat->hermitian_set = PETSC_FALSE; 5429 mat->structurally_symmetric_set = PETSC_FALSE; 5430 } 5431 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5432 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5433 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5434 } 5435 #endif 5436 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5437 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5438 5439 if (mat->checksymmetryonassembly) { 5440 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5441 if (flg) { 5442 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5443 } else { 5444 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5445 } 5446 } 5447 if (mat->nullsp && mat->checknullspaceonassembly) { 5448 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5449 } 5450 } 5451 inassm--; 5452 PetscFunctionReturn(0); 5453 } 5454 5455 /*@ 5456 MatSetOption - Sets a parameter option for a matrix. Some options 5457 may be specific to certain storage formats. Some options 5458 determine how values will be inserted (or added). Sorted, 5459 row-oriented input will generally assemble the fastest. The default 5460 is row-oriented. 5461 5462 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5463 5464 Input Parameters: 5465 + mat - the matrix 5466 . option - the option, one of those listed below (and possibly others), 5467 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5468 5469 Options Describing Matrix Structure: 5470 + MAT_SPD - symmetric positive definite 5471 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5472 . MAT_HERMITIAN - transpose is the complex conjugation 5473 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5474 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5475 you set to be kept with all future use of the matrix 5476 including after MatAssemblyBegin/End() which could 5477 potentially change the symmetry structure, i.e. you 5478 KNOW the matrix will ALWAYS have the property you set. 5479 5480 5481 Options For Use with MatSetValues(): 5482 Insert a logically dense subblock, which can be 5483 . MAT_ROW_ORIENTED - row-oriented (default) 5484 5485 Note these options reflect the data you pass in with MatSetValues(); it has 5486 nothing to do with how the data is stored internally in the matrix 5487 data structure. 5488 5489 When (re)assembling a matrix, we can restrict the input for 5490 efficiency/debugging purposes. These options include: 5491 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5492 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5493 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5494 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5495 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5496 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5497 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5498 performance for very large process counts. 5499 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5500 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5501 functions, instead sending only neighbor messages. 5502 5503 Notes: 5504 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5505 5506 Some options are relevant only for particular matrix types and 5507 are thus ignored by others. Other options are not supported by 5508 certain matrix types and will generate an error message if set. 5509 5510 If using a Fortran 77 module to compute a matrix, one may need to 5511 use the column-oriented option (or convert to the row-oriented 5512 format). 5513 5514 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5515 that would generate a new entry in the nonzero structure is instead 5516 ignored. Thus, if memory has not alredy been allocated for this particular 5517 data, then the insertion is ignored. For dense matrices, in which 5518 the entire array is allocated, no entries are ever ignored. 5519 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5520 5521 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5522 that would generate a new entry in the nonzero structure instead produces 5523 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 5524 5525 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5526 that would generate a new entry that has not been preallocated will 5527 instead produce an error. (Currently supported for AIJ and BAIJ formats 5528 only.) This is a useful flag when debugging matrix memory preallocation. 5529 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5530 5531 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5532 other processors should be dropped, rather than stashed. 5533 This is useful if you know that the "owning" processor is also 5534 always generating the correct matrix entries, so that PETSc need 5535 not transfer duplicate entries generated on another processor. 5536 5537 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5538 searches during matrix assembly. When this flag is set, the hash table 5539 is created during the first Matrix Assembly. This hash table is 5540 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5541 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5542 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5543 supported by MATMPIBAIJ format only. 5544 5545 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5546 are kept in the nonzero structure 5547 5548 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5549 a zero location in the matrix 5550 5551 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5552 5553 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5554 zero row routines and thus improves performance for very large process counts. 5555 5556 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5557 part of the matrix (since they should match the upper triangular part). 5558 5559 Notes: 5560 Can only be called after MatSetSizes() and MatSetType() have been set. 5561 5562 Level: intermediate 5563 5564 Concepts: matrices^setting options 5565 5566 .seealso: MatOption, Mat 5567 5568 @*/ 5569 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5570 { 5571 PetscErrorCode ierr; 5572 5573 PetscFunctionBegin; 5574 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5575 PetscValidType(mat,1); 5576 if (op > 0) { 5577 PetscValidLogicalCollectiveEnum(mat,op,2); 5578 PetscValidLogicalCollectiveBool(mat,flg,3); 5579 } 5580 5581 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); 5582 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()"); 5583 5584 switch (op) { 5585 case MAT_NO_OFF_PROC_ENTRIES: 5586 mat->nooffprocentries = flg; 5587 PetscFunctionReturn(0); 5588 break; 5589 case MAT_SUBSET_OFF_PROC_ENTRIES: 5590 mat->subsetoffprocentries = flg; 5591 PetscFunctionReturn(0); 5592 case MAT_NO_OFF_PROC_ZERO_ROWS: 5593 mat->nooffproczerorows = flg; 5594 PetscFunctionReturn(0); 5595 break; 5596 case MAT_SPD: 5597 mat->spd_set = PETSC_TRUE; 5598 mat->spd = flg; 5599 if (flg) { 5600 mat->symmetric = PETSC_TRUE; 5601 mat->structurally_symmetric = PETSC_TRUE; 5602 mat->symmetric_set = PETSC_TRUE; 5603 mat->structurally_symmetric_set = PETSC_TRUE; 5604 } 5605 break; 5606 case MAT_SYMMETRIC: 5607 mat->symmetric = flg; 5608 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5609 mat->symmetric_set = PETSC_TRUE; 5610 mat->structurally_symmetric_set = flg; 5611 #if !defined(PETSC_USE_COMPLEX) 5612 mat->hermitian = flg; 5613 mat->hermitian_set = PETSC_TRUE; 5614 #endif 5615 break; 5616 case MAT_HERMITIAN: 5617 mat->hermitian = flg; 5618 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5619 mat->hermitian_set = PETSC_TRUE; 5620 mat->structurally_symmetric_set = flg; 5621 #if !defined(PETSC_USE_COMPLEX) 5622 mat->symmetric = flg; 5623 mat->symmetric_set = PETSC_TRUE; 5624 #endif 5625 break; 5626 case MAT_STRUCTURALLY_SYMMETRIC: 5627 mat->structurally_symmetric = flg; 5628 mat->structurally_symmetric_set = PETSC_TRUE; 5629 break; 5630 case MAT_SYMMETRY_ETERNAL: 5631 mat->symmetric_eternal = flg; 5632 break; 5633 case MAT_STRUCTURE_ONLY: 5634 mat->structure_only = flg; 5635 break; 5636 default: 5637 break; 5638 } 5639 if (mat->ops->setoption) { 5640 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5641 } 5642 PetscFunctionReturn(0); 5643 } 5644 5645 /*@ 5646 MatGetOption - Gets a parameter option that has been set for a matrix. 5647 5648 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5649 5650 Input Parameters: 5651 + mat - the matrix 5652 - option - the option, this only responds to certain options, check the code for which ones 5653 5654 Output Parameter: 5655 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5656 5657 Notes: 5658 Can only be called after MatSetSizes() and MatSetType() have been set. 5659 5660 Level: intermediate 5661 5662 Concepts: matrices^setting options 5663 5664 .seealso: MatOption, MatSetOption() 5665 5666 @*/ 5667 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5668 { 5669 PetscFunctionBegin; 5670 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5671 PetscValidType(mat,1); 5672 5673 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); 5674 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()"); 5675 5676 switch (op) { 5677 case MAT_NO_OFF_PROC_ENTRIES: 5678 *flg = mat->nooffprocentries; 5679 break; 5680 case MAT_NO_OFF_PROC_ZERO_ROWS: 5681 *flg = mat->nooffproczerorows; 5682 break; 5683 case MAT_SYMMETRIC: 5684 *flg = mat->symmetric; 5685 break; 5686 case MAT_HERMITIAN: 5687 *flg = mat->hermitian; 5688 break; 5689 case MAT_STRUCTURALLY_SYMMETRIC: 5690 *flg = mat->structurally_symmetric; 5691 break; 5692 case MAT_SYMMETRY_ETERNAL: 5693 *flg = mat->symmetric_eternal; 5694 break; 5695 case MAT_SPD: 5696 *flg = mat->spd; 5697 break; 5698 default: 5699 break; 5700 } 5701 PetscFunctionReturn(0); 5702 } 5703 5704 /*@ 5705 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5706 this routine retains the old nonzero structure. 5707 5708 Logically Collective on Mat 5709 5710 Input Parameters: 5711 . mat - the matrix 5712 5713 Level: intermediate 5714 5715 Notes: 5716 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. 5717 See the Performance chapter of the users manual for information on preallocating matrices. 5718 5719 Concepts: matrices^zeroing 5720 5721 .seealso: MatZeroRows() 5722 @*/ 5723 PetscErrorCode MatZeroEntries(Mat mat) 5724 { 5725 PetscErrorCode ierr; 5726 5727 PetscFunctionBegin; 5728 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5729 PetscValidType(mat,1); 5730 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5731 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"); 5732 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5733 MatCheckPreallocated(mat,1); 5734 5735 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5736 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5737 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5738 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5739 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5740 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5741 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5742 } 5743 #endif 5744 PetscFunctionReturn(0); 5745 } 5746 5747 /*@ 5748 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5749 of a set of rows and columns of a matrix. 5750 5751 Collective on Mat 5752 5753 Input Parameters: 5754 + mat - the matrix 5755 . numRows - the number of rows to remove 5756 . rows - the global row indices 5757 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5758 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5759 - b - optional vector of right hand side, that will be adjusted by provided solution 5760 5761 Notes: 5762 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5763 5764 The user can set a value in the diagonal entry (or for the AIJ and 5765 row formats can optionally remove the main diagonal entry from the 5766 nonzero structure as well, by passing 0.0 as the final argument). 5767 5768 For the parallel case, all processes that share the matrix (i.e., 5769 those in the communicator used for matrix creation) MUST call this 5770 routine, regardless of whether any rows being zeroed are owned by 5771 them. 5772 5773 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5774 list only rows local to itself). 5775 5776 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5777 5778 Level: intermediate 5779 5780 Concepts: matrices^zeroing rows 5781 5782 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5783 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5784 @*/ 5785 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5786 { 5787 PetscErrorCode ierr; 5788 5789 PetscFunctionBegin; 5790 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5791 PetscValidType(mat,1); 5792 if (numRows) PetscValidIntPointer(rows,3); 5793 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5794 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5795 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5796 MatCheckPreallocated(mat,1); 5797 5798 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5799 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5800 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5801 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5802 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5803 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5804 } 5805 #endif 5806 PetscFunctionReturn(0); 5807 } 5808 5809 /*@ 5810 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5811 of a set of rows and columns of a matrix. 5812 5813 Collective on Mat 5814 5815 Input Parameters: 5816 + mat - the matrix 5817 . is - the rows to zero 5818 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5819 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5820 - b - optional vector of right hand side, that will be adjusted by provided solution 5821 5822 Notes: 5823 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5824 5825 The user can set a value in the diagonal entry (or for the AIJ and 5826 row formats can optionally remove the main diagonal entry from the 5827 nonzero structure as well, by passing 0.0 as the final argument). 5828 5829 For the parallel case, all processes that share the matrix (i.e., 5830 those in the communicator used for matrix creation) MUST call this 5831 routine, regardless of whether any rows being zeroed are owned by 5832 them. 5833 5834 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5835 list only rows local to itself). 5836 5837 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5838 5839 Level: intermediate 5840 5841 Concepts: matrices^zeroing rows 5842 5843 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5844 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5845 @*/ 5846 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5847 { 5848 PetscErrorCode ierr; 5849 PetscInt numRows; 5850 const PetscInt *rows; 5851 5852 PetscFunctionBegin; 5853 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5854 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5855 PetscValidType(mat,1); 5856 PetscValidType(is,2); 5857 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5858 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5859 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5860 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5861 PetscFunctionReturn(0); 5862 } 5863 5864 /*@ 5865 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5866 of a set of rows of a matrix. 5867 5868 Collective on Mat 5869 5870 Input Parameters: 5871 + mat - the matrix 5872 . numRows - the number of rows to remove 5873 . rows - the global row indices 5874 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5875 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5876 - b - optional vector of right hand side, that will be adjusted by provided solution 5877 5878 Notes: 5879 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5880 but does not release memory. For the dense and block diagonal 5881 formats this does not alter the nonzero structure. 5882 5883 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5884 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5885 merely zeroed. 5886 5887 The user can set a value in the diagonal entry (or for the AIJ and 5888 row formats can optionally remove the main diagonal entry from the 5889 nonzero structure as well, by passing 0.0 as the final argument). 5890 5891 For the parallel case, all processes that share the matrix (i.e., 5892 those in the communicator used for matrix creation) MUST call this 5893 routine, regardless of whether any rows being zeroed are owned by 5894 them. 5895 5896 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5897 list only rows local to itself). 5898 5899 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5900 owns that are to be zeroed. This saves a global synchronization in the implementation. 5901 5902 Level: intermediate 5903 5904 Concepts: matrices^zeroing rows 5905 5906 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5907 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5908 @*/ 5909 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5910 { 5911 PetscErrorCode ierr; 5912 5913 PetscFunctionBegin; 5914 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5915 PetscValidType(mat,1); 5916 if (numRows) PetscValidIntPointer(rows,3); 5917 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5918 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5919 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5920 MatCheckPreallocated(mat,1); 5921 5922 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5923 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5924 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5925 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5926 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5927 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5928 } 5929 #endif 5930 PetscFunctionReturn(0); 5931 } 5932 5933 /*@ 5934 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5935 of a set of rows of a matrix. 5936 5937 Collective on Mat 5938 5939 Input Parameters: 5940 + mat - the matrix 5941 . is - index set of rows to remove 5942 . diag - value put in all diagonals of eliminated rows 5943 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5944 - b - optional vector of right hand side, that will be adjusted by provided solution 5945 5946 Notes: 5947 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5948 but does not release memory. For the dense and block diagonal 5949 formats this does not alter the nonzero structure. 5950 5951 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5952 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5953 merely zeroed. 5954 5955 The user can set a value in the diagonal entry (or for the AIJ and 5956 row formats can optionally remove the main diagonal entry from the 5957 nonzero structure as well, by passing 0.0 as the final argument). 5958 5959 For the parallel case, all processes that share the matrix (i.e., 5960 those in the communicator used for matrix creation) MUST call this 5961 routine, regardless of whether any rows being zeroed are owned by 5962 them. 5963 5964 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5965 list only rows local to itself). 5966 5967 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5968 owns that are to be zeroed. This saves a global synchronization in the implementation. 5969 5970 Level: intermediate 5971 5972 Concepts: matrices^zeroing rows 5973 5974 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5975 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5976 @*/ 5977 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5978 { 5979 PetscInt numRows; 5980 const PetscInt *rows; 5981 PetscErrorCode ierr; 5982 5983 PetscFunctionBegin; 5984 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5985 PetscValidType(mat,1); 5986 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5987 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5988 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5989 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5990 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5991 PetscFunctionReturn(0); 5992 } 5993 5994 /*@ 5995 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5996 of a set of rows of a matrix. These rows must be local to the process. 5997 5998 Collective on Mat 5999 6000 Input Parameters: 6001 + mat - the matrix 6002 . numRows - the number of rows to remove 6003 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6004 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6005 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6006 - b - optional vector of right hand side, that will be adjusted by provided solution 6007 6008 Notes: 6009 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6010 but does not release memory. For the dense and block diagonal 6011 formats this does not alter the nonzero structure. 6012 6013 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6014 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6015 merely zeroed. 6016 6017 The user can set a value in the diagonal entry (or for the AIJ and 6018 row formats can optionally remove the main diagonal entry from the 6019 nonzero structure as well, by passing 0.0 as the final argument). 6020 6021 For the parallel case, all processes that share the matrix (i.e., 6022 those in the communicator used for matrix creation) MUST call this 6023 routine, regardless of whether any rows being zeroed are owned by 6024 them. 6025 6026 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6027 list only rows local to itself). 6028 6029 The grid coordinates are across the entire grid, not just the local portion 6030 6031 In Fortran idxm and idxn should be declared as 6032 $ MatStencil idxm(4,m) 6033 and the values inserted using 6034 $ idxm(MatStencil_i,1) = i 6035 $ idxm(MatStencil_j,1) = j 6036 $ idxm(MatStencil_k,1) = k 6037 $ idxm(MatStencil_c,1) = c 6038 etc 6039 6040 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6041 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6042 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6043 DM_BOUNDARY_PERIODIC boundary type. 6044 6045 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 6046 a single value per point) you can skip filling those indices. 6047 6048 Level: intermediate 6049 6050 Concepts: matrices^zeroing rows 6051 6052 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6053 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6054 @*/ 6055 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6056 { 6057 PetscInt dim = mat->stencil.dim; 6058 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6059 PetscInt *dims = mat->stencil.dims+1; 6060 PetscInt *starts = mat->stencil.starts; 6061 PetscInt *dxm = (PetscInt*) rows; 6062 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6063 PetscErrorCode ierr; 6064 6065 PetscFunctionBegin; 6066 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6067 PetscValidType(mat,1); 6068 if (numRows) PetscValidIntPointer(rows,3); 6069 6070 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6071 for (i = 0; i < numRows; ++i) { 6072 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6073 for (j = 0; j < 3-sdim; ++j) dxm++; 6074 /* Local index in X dir */ 6075 tmp = *dxm++ - starts[0]; 6076 /* Loop over remaining dimensions */ 6077 for (j = 0; j < dim-1; ++j) { 6078 /* If nonlocal, set index to be negative */ 6079 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6080 /* Update local index */ 6081 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6082 } 6083 /* Skip component slot if necessary */ 6084 if (mat->stencil.noc) dxm++; 6085 /* Local row number */ 6086 if (tmp >= 0) { 6087 jdxm[numNewRows++] = tmp; 6088 } 6089 } 6090 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6091 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6092 PetscFunctionReturn(0); 6093 } 6094 6095 /*@ 6096 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6097 of a set of rows and columns of a matrix. 6098 6099 Collective on Mat 6100 6101 Input Parameters: 6102 + mat - the matrix 6103 . numRows - the number of rows/columns to remove 6104 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6105 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6106 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6107 - b - optional vector of right hand side, that will be adjusted by provided solution 6108 6109 Notes: 6110 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6111 but does not release memory. For the dense and block diagonal 6112 formats this does not alter the nonzero structure. 6113 6114 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6115 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6116 merely zeroed. 6117 6118 The user can set a value in the diagonal entry (or for the AIJ and 6119 row formats can optionally remove the main diagonal entry from the 6120 nonzero structure as well, by passing 0.0 as the final argument). 6121 6122 For the parallel case, all processes that share the matrix (i.e., 6123 those in the communicator used for matrix creation) MUST call this 6124 routine, regardless of whether any rows being zeroed are owned by 6125 them. 6126 6127 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6128 list only rows local to itself, but the row/column numbers are given in local numbering). 6129 6130 The grid coordinates are across the entire grid, not just the local portion 6131 6132 In Fortran idxm and idxn should be declared as 6133 $ MatStencil idxm(4,m) 6134 and the values inserted using 6135 $ idxm(MatStencil_i,1) = i 6136 $ idxm(MatStencil_j,1) = j 6137 $ idxm(MatStencil_k,1) = k 6138 $ idxm(MatStencil_c,1) = c 6139 etc 6140 6141 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6142 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6143 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6144 DM_BOUNDARY_PERIODIC boundary type. 6145 6146 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 6147 a single value per point) you can skip filling those indices. 6148 6149 Level: intermediate 6150 6151 Concepts: matrices^zeroing rows 6152 6153 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6154 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6155 @*/ 6156 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6157 { 6158 PetscInt dim = mat->stencil.dim; 6159 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6160 PetscInt *dims = mat->stencil.dims+1; 6161 PetscInt *starts = mat->stencil.starts; 6162 PetscInt *dxm = (PetscInt*) rows; 6163 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6164 PetscErrorCode ierr; 6165 6166 PetscFunctionBegin; 6167 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6168 PetscValidType(mat,1); 6169 if (numRows) PetscValidIntPointer(rows,3); 6170 6171 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6172 for (i = 0; i < numRows; ++i) { 6173 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6174 for (j = 0; j < 3-sdim; ++j) dxm++; 6175 /* Local index in X dir */ 6176 tmp = *dxm++ - starts[0]; 6177 /* Loop over remaining dimensions */ 6178 for (j = 0; j < dim-1; ++j) { 6179 /* If nonlocal, set index to be negative */ 6180 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6181 /* Update local index */ 6182 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6183 } 6184 /* Skip component slot if necessary */ 6185 if (mat->stencil.noc) dxm++; 6186 /* Local row number */ 6187 if (tmp >= 0) { 6188 jdxm[numNewRows++] = tmp; 6189 } 6190 } 6191 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6192 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6193 PetscFunctionReturn(0); 6194 } 6195 6196 /*@C 6197 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6198 of a set of rows of a matrix; using local numbering of rows. 6199 6200 Collective on Mat 6201 6202 Input Parameters: 6203 + mat - the matrix 6204 . numRows - the number of rows to remove 6205 . rows - the global row indices 6206 . diag - value put in all diagonals of eliminated rows 6207 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6208 - b - optional vector of right hand side, that will be adjusted by provided solution 6209 6210 Notes: 6211 Before calling MatZeroRowsLocal(), the user must first set the 6212 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6213 6214 For the AIJ matrix formats this removes the old nonzero structure, 6215 but does not release memory. For the dense and block diagonal 6216 formats this does not alter the nonzero structure. 6217 6218 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6219 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6220 merely zeroed. 6221 6222 The user can set a value in the diagonal entry (or for the AIJ and 6223 row formats can optionally remove the main diagonal entry from the 6224 nonzero structure as well, by passing 0.0 as the final argument). 6225 6226 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6227 owns that are to be zeroed. This saves a global synchronization in the implementation. 6228 6229 Level: intermediate 6230 6231 Concepts: matrices^zeroing 6232 6233 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6234 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6235 @*/ 6236 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6237 { 6238 PetscErrorCode ierr; 6239 6240 PetscFunctionBegin; 6241 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6242 PetscValidType(mat,1); 6243 if (numRows) PetscValidIntPointer(rows,3); 6244 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6245 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6246 MatCheckPreallocated(mat,1); 6247 6248 if (mat->ops->zerorowslocal) { 6249 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6250 } else { 6251 IS is, newis; 6252 const PetscInt *newRows; 6253 6254 if (!mat->rmap->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->rmap->mapping,is,&newis);CHKERRQ(ierr); 6257 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6258 ierr = (*mat->ops->zerorows)(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 } 6263 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6264 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6265 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6266 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6267 } 6268 #endif 6269 PetscFunctionReturn(0); 6270 } 6271 6272 /*@ 6273 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6274 of a set of rows of a matrix; using local numbering of rows. 6275 6276 Collective on Mat 6277 6278 Input Parameters: 6279 + mat - the matrix 6280 . is - index set of rows to remove 6281 . diag - value put in all diagonals of eliminated rows 6282 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6283 - b - optional vector of right hand side, that will be adjusted by provided solution 6284 6285 Notes: 6286 Before calling MatZeroRowsLocalIS(), the user must first set the 6287 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6288 6289 For the AIJ matrix formats this removes the old nonzero structure, 6290 but does not release memory. For the dense and block diagonal 6291 formats this does not alter the nonzero structure. 6292 6293 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6294 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6295 merely zeroed. 6296 6297 The user can set a value in the diagonal entry (or for the AIJ and 6298 row formats can optionally remove the main diagonal entry from the 6299 nonzero structure as well, by passing 0.0 as the final argument). 6300 6301 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6302 owns that are to be zeroed. This saves a global synchronization in the implementation. 6303 6304 Level: intermediate 6305 6306 Concepts: matrices^zeroing 6307 6308 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6309 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6310 @*/ 6311 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6312 { 6313 PetscErrorCode ierr; 6314 PetscInt numRows; 6315 const PetscInt *rows; 6316 6317 PetscFunctionBegin; 6318 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6319 PetscValidType(mat,1); 6320 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6321 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6322 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6323 MatCheckPreallocated(mat,1); 6324 6325 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6326 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6327 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6328 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6329 PetscFunctionReturn(0); 6330 } 6331 6332 /*@ 6333 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6334 of a set of rows and columns of a matrix; using local numbering of rows. 6335 6336 Collective on Mat 6337 6338 Input Parameters: 6339 + mat - the matrix 6340 . numRows - the number of rows to remove 6341 . rows - the global row indices 6342 . diag - value put in all diagonals of eliminated rows 6343 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6344 - b - optional vector of right hand side, that will be adjusted by provided solution 6345 6346 Notes: 6347 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6348 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6349 6350 The user can set a value in the diagonal entry (or for the AIJ and 6351 row formats can optionally remove the main diagonal entry from the 6352 nonzero structure as well, by passing 0.0 as the final argument). 6353 6354 Level: intermediate 6355 6356 Concepts: matrices^zeroing 6357 6358 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6359 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6360 @*/ 6361 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6362 { 6363 PetscErrorCode ierr; 6364 IS is, newis; 6365 const PetscInt *newRows; 6366 6367 PetscFunctionBegin; 6368 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6369 PetscValidType(mat,1); 6370 if (numRows) PetscValidIntPointer(rows,3); 6371 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6372 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6373 MatCheckPreallocated(mat,1); 6374 6375 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6376 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6377 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6378 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6379 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6380 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6381 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6382 ierr = ISDestroy(&is);CHKERRQ(ierr); 6383 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6384 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6385 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6386 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6387 } 6388 #endif 6389 PetscFunctionReturn(0); 6390 } 6391 6392 /*@ 6393 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6394 of a set of rows and columns of a matrix; using local numbering of rows. 6395 6396 Collective on Mat 6397 6398 Input Parameters: 6399 + mat - the matrix 6400 . is - index set of rows to remove 6401 . diag - value put in all diagonals of eliminated rows 6402 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6403 - b - optional vector of right hand side, that will be adjusted by provided solution 6404 6405 Notes: 6406 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6407 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6408 6409 The user can set a value in the diagonal entry (or for the AIJ and 6410 row formats can optionally remove the main diagonal entry from the 6411 nonzero structure as well, by passing 0.0 as the final argument). 6412 6413 Level: intermediate 6414 6415 Concepts: matrices^zeroing 6416 6417 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6418 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6419 @*/ 6420 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6421 { 6422 PetscErrorCode ierr; 6423 PetscInt numRows; 6424 const PetscInt *rows; 6425 6426 PetscFunctionBegin; 6427 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6428 PetscValidType(mat,1); 6429 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6430 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6431 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6432 MatCheckPreallocated(mat,1); 6433 6434 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6435 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6436 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6437 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6438 PetscFunctionReturn(0); 6439 } 6440 6441 /*@C 6442 MatGetSize - Returns the numbers of rows and columns in a matrix. 6443 6444 Not Collective 6445 6446 Input Parameter: 6447 . mat - the matrix 6448 6449 Output Parameters: 6450 + m - the number of global rows 6451 - n - the number of global columns 6452 6453 Note: both output parameters can be NULL on input. 6454 6455 Level: beginner 6456 6457 Concepts: matrices^size 6458 6459 .seealso: MatGetLocalSize() 6460 @*/ 6461 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6462 { 6463 PetscFunctionBegin; 6464 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6465 if (m) *m = mat->rmap->N; 6466 if (n) *n = mat->cmap->N; 6467 PetscFunctionReturn(0); 6468 } 6469 6470 /*@C 6471 MatGetLocalSize - Returns the number of rows and columns in a matrix 6472 stored locally. This information may be implementation dependent, so 6473 use with care. 6474 6475 Not Collective 6476 6477 Input Parameters: 6478 . mat - the matrix 6479 6480 Output Parameters: 6481 + m - the number of local rows 6482 - n - the number of local columns 6483 6484 Note: both output parameters can be NULL on input. 6485 6486 Level: beginner 6487 6488 Concepts: matrices^local size 6489 6490 .seealso: MatGetSize() 6491 @*/ 6492 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6493 { 6494 PetscFunctionBegin; 6495 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6496 if (m) PetscValidIntPointer(m,2); 6497 if (n) PetscValidIntPointer(n,3); 6498 if (m) *m = mat->rmap->n; 6499 if (n) *n = mat->cmap->n; 6500 PetscFunctionReturn(0); 6501 } 6502 6503 /*@C 6504 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6505 this processor. (The columns of the "diagonal block") 6506 6507 Not Collective, unless matrix has not been allocated, then collective on Mat 6508 6509 Input Parameters: 6510 . mat - the matrix 6511 6512 Output Parameters: 6513 + m - the global index of the first local column 6514 - n - one more than the global index of the last local column 6515 6516 Notes: 6517 both output parameters can be NULL on input. 6518 6519 Level: developer 6520 6521 Concepts: matrices^column ownership 6522 6523 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6524 6525 @*/ 6526 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6527 { 6528 PetscFunctionBegin; 6529 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6530 PetscValidType(mat,1); 6531 if (m) PetscValidIntPointer(m,2); 6532 if (n) PetscValidIntPointer(n,3); 6533 MatCheckPreallocated(mat,1); 6534 if (m) *m = mat->cmap->rstart; 6535 if (n) *n = mat->cmap->rend; 6536 PetscFunctionReturn(0); 6537 } 6538 6539 /*@C 6540 MatGetOwnershipRange - Returns the range of matrix rows owned by 6541 this processor, assuming that the matrix is laid out with the first 6542 n1 rows on the first processor, the next n2 rows on the second, etc. 6543 For certain parallel layouts this range may not be well defined. 6544 6545 Not Collective 6546 6547 Input Parameters: 6548 . mat - the matrix 6549 6550 Output Parameters: 6551 + m - the global index of the first local row 6552 - n - one more than the global index of the last local row 6553 6554 Note: Both output parameters can be NULL on input. 6555 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6556 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6557 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6558 6559 Level: beginner 6560 6561 Concepts: matrices^row ownership 6562 6563 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6564 6565 @*/ 6566 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6567 { 6568 PetscFunctionBegin; 6569 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6570 PetscValidType(mat,1); 6571 if (m) PetscValidIntPointer(m,2); 6572 if (n) PetscValidIntPointer(n,3); 6573 MatCheckPreallocated(mat,1); 6574 if (m) *m = mat->rmap->rstart; 6575 if (n) *n = mat->rmap->rend; 6576 PetscFunctionReturn(0); 6577 } 6578 6579 /*@C 6580 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6581 each process 6582 6583 Not Collective, unless matrix has not been allocated, then collective on Mat 6584 6585 Input Parameters: 6586 . mat - the matrix 6587 6588 Output Parameters: 6589 . ranges - start of each processors portion plus one more than the total length at the end 6590 6591 Level: beginner 6592 6593 Concepts: matrices^row ownership 6594 6595 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6596 6597 @*/ 6598 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6599 { 6600 PetscErrorCode ierr; 6601 6602 PetscFunctionBegin; 6603 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6604 PetscValidType(mat,1); 6605 MatCheckPreallocated(mat,1); 6606 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6607 PetscFunctionReturn(0); 6608 } 6609 6610 /*@C 6611 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6612 this processor. (The columns of the "diagonal blocks" for each process) 6613 6614 Not Collective, unless matrix has not been allocated, then collective on Mat 6615 6616 Input Parameters: 6617 . mat - the matrix 6618 6619 Output Parameters: 6620 . ranges - start of each processors portion plus one more then the total length at the end 6621 6622 Level: beginner 6623 6624 Concepts: matrices^column ownership 6625 6626 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6627 6628 @*/ 6629 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6630 { 6631 PetscErrorCode ierr; 6632 6633 PetscFunctionBegin; 6634 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6635 PetscValidType(mat,1); 6636 MatCheckPreallocated(mat,1); 6637 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6638 PetscFunctionReturn(0); 6639 } 6640 6641 /*@C 6642 MatGetOwnershipIS - Get row and column ownership as index sets 6643 6644 Not Collective 6645 6646 Input Arguments: 6647 . A - matrix of type Elemental 6648 6649 Output Arguments: 6650 + rows - rows in which this process owns elements 6651 . cols - columns in which this process owns elements 6652 6653 Level: intermediate 6654 6655 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6656 @*/ 6657 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6658 { 6659 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6660 6661 PetscFunctionBegin; 6662 MatCheckPreallocated(A,1); 6663 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6664 if (f) { 6665 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6666 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6667 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6668 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6669 } 6670 PetscFunctionReturn(0); 6671 } 6672 6673 /*@C 6674 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6675 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6676 to complete the factorization. 6677 6678 Collective on Mat 6679 6680 Input Parameters: 6681 + mat - the matrix 6682 . row - row permutation 6683 . column - column permutation 6684 - info - structure containing 6685 $ levels - number of levels of fill. 6686 $ expected fill - as ratio of original fill. 6687 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6688 missing diagonal entries) 6689 6690 Output Parameters: 6691 . fact - new matrix that has been symbolically factored 6692 6693 Notes: 6694 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6695 6696 Most users should employ the simplified KSP interface for linear solvers 6697 instead of working directly with matrix algebra routines such as this. 6698 See, e.g., KSPCreate(). 6699 6700 Level: developer 6701 6702 Concepts: matrices^symbolic LU factorization 6703 Concepts: matrices^factorization 6704 Concepts: LU^symbolic factorization 6705 6706 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6707 MatGetOrdering(), MatFactorInfo 6708 6709 Note: this uses the definition of level of fill as in Y. Saad, 2003 6710 6711 Developer Note: fortran interface is not autogenerated as the f90 6712 interface defintion cannot be generated correctly [due to MatFactorInfo] 6713 6714 References: 6715 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6716 @*/ 6717 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6718 { 6719 PetscErrorCode ierr; 6720 6721 PetscFunctionBegin; 6722 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6723 PetscValidType(mat,1); 6724 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6725 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6726 PetscValidPointer(info,4); 6727 PetscValidPointer(fact,5); 6728 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6729 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6730 if (!(fact)->ops->ilufactorsymbolic) { 6731 MatSolverType spackage; 6732 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6733 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6734 } 6735 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6736 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6737 MatCheckPreallocated(mat,2); 6738 6739 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6740 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6741 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6742 PetscFunctionReturn(0); 6743 } 6744 6745 /*@C 6746 MatICCFactorSymbolic - Performs symbolic incomplete 6747 Cholesky factorization for a symmetric matrix. Use 6748 MatCholeskyFactorNumeric() to complete the factorization. 6749 6750 Collective on Mat 6751 6752 Input Parameters: 6753 + mat - the matrix 6754 . perm - row and column permutation 6755 - info - structure containing 6756 $ levels - number of levels of fill. 6757 $ expected fill - as ratio of original fill. 6758 6759 Output Parameter: 6760 . fact - the factored matrix 6761 6762 Notes: 6763 Most users should employ the KSP interface for linear solvers 6764 instead of working directly with matrix algebra routines such as this. 6765 See, e.g., KSPCreate(). 6766 6767 Level: developer 6768 6769 Concepts: matrices^symbolic incomplete Cholesky factorization 6770 Concepts: matrices^factorization 6771 Concepts: Cholsky^symbolic factorization 6772 6773 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6774 6775 Note: this uses the definition of level of fill as in Y. Saad, 2003 6776 6777 Developer Note: fortran interface is not autogenerated as the f90 6778 interface defintion cannot be generated correctly [due to MatFactorInfo] 6779 6780 References: 6781 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6782 @*/ 6783 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6784 { 6785 PetscErrorCode ierr; 6786 6787 PetscFunctionBegin; 6788 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6789 PetscValidType(mat,1); 6790 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6791 PetscValidPointer(info,3); 6792 PetscValidPointer(fact,4); 6793 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6794 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6795 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6796 if (!(fact)->ops->iccfactorsymbolic) { 6797 MatSolverType spackage; 6798 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6799 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6800 } 6801 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6802 MatCheckPreallocated(mat,2); 6803 6804 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6805 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6806 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6807 PetscFunctionReturn(0); 6808 } 6809 6810 /*@C 6811 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6812 points to an array of valid matrices, they may be reused to store the new 6813 submatrices. 6814 6815 Collective on Mat 6816 6817 Input Parameters: 6818 + mat - the matrix 6819 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6820 . irow, icol - index sets of rows and columns to extract 6821 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6822 6823 Output Parameter: 6824 . submat - the array of submatrices 6825 6826 Notes: 6827 MatCreateSubMatrices() can extract ONLY sequential submatrices 6828 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6829 to extract a parallel submatrix. 6830 6831 Some matrix types place restrictions on the row and column 6832 indices, such as that they be sorted or that they be equal to each other. 6833 6834 The index sets may not have duplicate entries. 6835 6836 When extracting submatrices from a parallel matrix, each processor can 6837 form a different submatrix by setting the rows and columns of its 6838 individual index sets according to the local submatrix desired. 6839 6840 When finished using the submatrices, the user should destroy 6841 them with MatDestroySubMatrices(). 6842 6843 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6844 original matrix has not changed from that last call to MatCreateSubMatrices(). 6845 6846 This routine creates the matrices in submat; you should NOT create them before 6847 calling it. It also allocates the array of matrix pointers submat. 6848 6849 For BAIJ matrices the index sets must respect the block structure, that is if they 6850 request one row/column in a block, they must request all rows/columns that are in 6851 that block. For example, if the block size is 2 you cannot request just row 0 and 6852 column 0. 6853 6854 Fortran Note: 6855 The Fortran interface is slightly different from that given below; it 6856 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6857 6858 Level: advanced 6859 6860 Concepts: matrices^accessing submatrices 6861 Concepts: submatrices 6862 6863 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6864 @*/ 6865 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6866 { 6867 PetscErrorCode ierr; 6868 PetscInt i; 6869 PetscBool eq; 6870 6871 PetscFunctionBegin; 6872 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6873 PetscValidType(mat,1); 6874 if (n) { 6875 PetscValidPointer(irow,3); 6876 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6877 PetscValidPointer(icol,4); 6878 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6879 } 6880 PetscValidPointer(submat,6); 6881 if (n && scall == MAT_REUSE_MATRIX) { 6882 PetscValidPointer(*submat,6); 6883 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6884 } 6885 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6886 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6887 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6888 MatCheckPreallocated(mat,1); 6889 6890 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6891 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6892 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6893 for (i=0; i<n; i++) { 6894 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6895 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6896 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6897 if (eq) { 6898 if (mat->symmetric) { 6899 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6900 } else if (mat->hermitian) { 6901 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6902 } else if (mat->structurally_symmetric) { 6903 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6904 } 6905 } 6906 } 6907 } 6908 PetscFunctionReturn(0); 6909 } 6910 6911 /*@C 6912 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6913 6914 Collective on Mat 6915 6916 Input Parameters: 6917 + mat - the matrix 6918 . n - the number of submatrixes to be extracted 6919 . irow, icol - index sets of rows and columns to extract 6920 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6921 6922 Output Parameter: 6923 . submat - the array of submatrices 6924 6925 Level: advanced 6926 6927 Concepts: matrices^accessing submatrices 6928 Concepts: submatrices 6929 6930 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6931 @*/ 6932 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6933 { 6934 PetscErrorCode ierr; 6935 PetscInt i; 6936 PetscBool eq; 6937 6938 PetscFunctionBegin; 6939 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6940 PetscValidType(mat,1); 6941 if (n) { 6942 PetscValidPointer(irow,3); 6943 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6944 PetscValidPointer(icol,4); 6945 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6946 } 6947 PetscValidPointer(submat,6); 6948 if (n && scall == MAT_REUSE_MATRIX) { 6949 PetscValidPointer(*submat,6); 6950 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6951 } 6952 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6953 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6954 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6955 MatCheckPreallocated(mat,1); 6956 6957 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6958 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6959 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6960 for (i=0; i<n; i++) { 6961 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6962 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6963 if (eq) { 6964 if (mat->symmetric) { 6965 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6966 } else if (mat->hermitian) { 6967 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6968 } else if (mat->structurally_symmetric) { 6969 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6970 } 6971 } 6972 } 6973 } 6974 PetscFunctionReturn(0); 6975 } 6976 6977 /*@C 6978 MatDestroyMatrices - Destroys an array of matrices. 6979 6980 Collective on Mat 6981 6982 Input Parameters: 6983 + n - the number of local matrices 6984 - mat - the matrices (note that this is a pointer to the array of matrices) 6985 6986 Level: advanced 6987 6988 Notes: 6989 Frees not only the matrices, but also the array that contains the matrices 6990 In Fortran will not free the array. 6991 6992 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6993 @*/ 6994 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6995 { 6996 PetscErrorCode ierr; 6997 PetscInt i; 6998 6999 PetscFunctionBegin; 7000 if (!*mat) PetscFunctionReturn(0); 7001 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 7002 PetscValidPointer(mat,2); 7003 7004 for (i=0; i<n; i++) { 7005 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 7006 } 7007 7008 /* memory is allocated even if n = 0 */ 7009 ierr = PetscFree(*mat);CHKERRQ(ierr); 7010 PetscFunctionReturn(0); 7011 } 7012 7013 /*@C 7014 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7015 7016 Collective on Mat 7017 7018 Input Parameters: 7019 + n - the number of local matrices 7020 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7021 sequence of MatCreateSubMatrices()) 7022 7023 Level: advanced 7024 7025 Notes: 7026 Frees not only the matrices, but also the array that contains the matrices 7027 In Fortran will not free the array. 7028 7029 .seealso: MatCreateSubMatrices() 7030 @*/ 7031 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7032 { 7033 PetscErrorCode ierr; 7034 Mat mat0; 7035 7036 PetscFunctionBegin; 7037 if (!*mat) PetscFunctionReturn(0); 7038 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7039 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 7040 PetscValidPointer(mat,2); 7041 7042 mat0 = (*mat)[0]; 7043 if (mat0 && mat0->ops->destroysubmatrices) { 7044 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 7045 } else { 7046 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 7047 } 7048 PetscFunctionReturn(0); 7049 } 7050 7051 /*@C 7052 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 7053 7054 Collective on Mat 7055 7056 Input Parameters: 7057 . mat - the matrix 7058 7059 Output Parameter: 7060 . matstruct - the sequential matrix with the nonzero structure of mat 7061 7062 Level: intermediate 7063 7064 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 7065 @*/ 7066 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7067 { 7068 PetscErrorCode ierr; 7069 7070 PetscFunctionBegin; 7071 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7072 PetscValidPointer(matstruct,2); 7073 7074 PetscValidType(mat,1); 7075 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7076 MatCheckPreallocated(mat,1); 7077 7078 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 7079 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7080 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 7081 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7082 PetscFunctionReturn(0); 7083 } 7084 7085 /*@C 7086 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7087 7088 Collective on Mat 7089 7090 Input Parameters: 7091 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7092 sequence of MatGetSequentialNonzeroStructure()) 7093 7094 Level: advanced 7095 7096 Notes: 7097 Frees not only the matrices, but also the array that contains the matrices 7098 7099 .seealso: MatGetSeqNonzeroStructure() 7100 @*/ 7101 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7102 { 7103 PetscErrorCode ierr; 7104 7105 PetscFunctionBegin; 7106 PetscValidPointer(mat,1); 7107 ierr = MatDestroy(mat);CHKERRQ(ierr); 7108 PetscFunctionReturn(0); 7109 } 7110 7111 /*@ 7112 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7113 replaces the index sets by larger ones that represent submatrices with 7114 additional overlap. 7115 7116 Collective on Mat 7117 7118 Input Parameters: 7119 + mat - the matrix 7120 . n - the number of index sets 7121 . is - the array of index sets (these index sets will changed during the call) 7122 - ov - the additional overlap requested 7123 7124 Options Database: 7125 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7126 7127 Level: developer 7128 7129 Concepts: overlap 7130 Concepts: ASM^computing overlap 7131 7132 .seealso: MatCreateSubMatrices() 7133 @*/ 7134 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7135 { 7136 PetscErrorCode ierr; 7137 7138 PetscFunctionBegin; 7139 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7140 PetscValidType(mat,1); 7141 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7142 if (n) { 7143 PetscValidPointer(is,3); 7144 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7145 } 7146 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7147 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7148 MatCheckPreallocated(mat,1); 7149 7150 if (!ov) PetscFunctionReturn(0); 7151 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7152 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7153 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7154 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7155 PetscFunctionReturn(0); 7156 } 7157 7158 7159 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7160 7161 /*@ 7162 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7163 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7164 additional overlap. 7165 7166 Collective on Mat 7167 7168 Input Parameters: 7169 + mat - the matrix 7170 . n - the number of index sets 7171 . is - the array of index sets (these index sets will changed during the call) 7172 - ov - the additional overlap requested 7173 7174 Options Database: 7175 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7176 7177 Level: developer 7178 7179 Concepts: overlap 7180 Concepts: ASM^computing overlap 7181 7182 .seealso: MatCreateSubMatrices() 7183 @*/ 7184 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7185 { 7186 PetscInt i; 7187 PetscErrorCode ierr; 7188 7189 PetscFunctionBegin; 7190 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7191 PetscValidType(mat,1); 7192 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7193 if (n) { 7194 PetscValidPointer(is,3); 7195 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7196 } 7197 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7198 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7199 MatCheckPreallocated(mat,1); 7200 if (!ov) PetscFunctionReturn(0); 7201 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7202 for(i=0; i<n; i++){ 7203 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7204 } 7205 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7206 PetscFunctionReturn(0); 7207 } 7208 7209 7210 7211 7212 /*@ 7213 MatGetBlockSize - Returns the matrix block size. 7214 7215 Not Collective 7216 7217 Input Parameter: 7218 . mat - the matrix 7219 7220 Output Parameter: 7221 . bs - block size 7222 7223 Notes: 7224 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7225 7226 If the block size has not been set yet this routine returns 1. 7227 7228 Level: intermediate 7229 7230 Concepts: matrices^block size 7231 7232 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7233 @*/ 7234 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7235 { 7236 PetscFunctionBegin; 7237 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7238 PetscValidIntPointer(bs,2); 7239 *bs = PetscAbs(mat->rmap->bs); 7240 PetscFunctionReturn(0); 7241 } 7242 7243 /*@ 7244 MatGetBlockSizes - Returns the matrix block row and column sizes. 7245 7246 Not Collective 7247 7248 Input Parameter: 7249 . mat - the matrix 7250 7251 Output Parameter: 7252 . rbs - row block size 7253 . cbs - column block size 7254 7255 Notes: 7256 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7257 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7258 7259 If a block size has not been set yet this routine returns 1. 7260 7261 Level: intermediate 7262 7263 Concepts: matrices^block size 7264 7265 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7266 @*/ 7267 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7268 { 7269 PetscFunctionBegin; 7270 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7271 if (rbs) PetscValidIntPointer(rbs,2); 7272 if (cbs) PetscValidIntPointer(cbs,3); 7273 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7274 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7275 PetscFunctionReturn(0); 7276 } 7277 7278 /*@ 7279 MatSetBlockSize - Sets the matrix block size. 7280 7281 Logically Collective on Mat 7282 7283 Input Parameters: 7284 + mat - the matrix 7285 - bs - block size 7286 7287 Notes: 7288 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7289 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7290 7291 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7292 is compatible with the matrix local sizes. 7293 7294 Level: intermediate 7295 7296 Concepts: matrices^block size 7297 7298 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7299 @*/ 7300 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7301 { 7302 PetscErrorCode ierr; 7303 7304 PetscFunctionBegin; 7305 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7306 PetscValidLogicalCollectiveInt(mat,bs,2); 7307 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7308 PetscFunctionReturn(0); 7309 } 7310 7311 /*@ 7312 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7313 7314 Logically Collective on Mat 7315 7316 Input Parameters: 7317 + mat - the matrix 7318 . nblocks - the number of blocks on this process 7319 - bsizes - the block sizes 7320 7321 Notes: 7322 Currently used by PCVPBJACOBI for SeqAIJ matrices 7323 7324 Level: intermediate 7325 7326 Concepts: matrices^block size 7327 7328 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7329 @*/ 7330 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7331 { 7332 PetscErrorCode ierr; 7333 PetscInt i,ncnt = 0, nlocal; 7334 7335 PetscFunctionBegin; 7336 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7337 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7338 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7339 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7340 if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal); 7341 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7342 mat->nblocks = nblocks; 7343 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7344 ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr); 7345 PetscFunctionReturn(0); 7346 } 7347 7348 /*@C 7349 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7350 7351 Logically Collective on Mat 7352 7353 Input Parameters: 7354 . mat - the matrix 7355 7356 Output Parameters: 7357 + nblocks - the number of blocks on this process 7358 - bsizes - the block sizes 7359 7360 Notes: Currently not supported from Fortran 7361 7362 Level: intermediate 7363 7364 Concepts: matrices^block size 7365 7366 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7367 @*/ 7368 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7369 { 7370 PetscFunctionBegin; 7371 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7372 *nblocks = mat->nblocks; 7373 *bsizes = mat->bsizes; 7374 PetscFunctionReturn(0); 7375 } 7376 7377 /*@ 7378 MatSetBlockSizes - Sets the matrix block row and column sizes. 7379 7380 Logically Collective on Mat 7381 7382 Input Parameters: 7383 + mat - the matrix 7384 - rbs - row block size 7385 - cbs - column block size 7386 7387 Notes: 7388 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7389 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7390 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7391 7392 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7393 are compatible with the matrix local sizes. 7394 7395 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7396 7397 Level: intermediate 7398 7399 Concepts: matrices^block size 7400 7401 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7402 @*/ 7403 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7404 { 7405 PetscErrorCode ierr; 7406 7407 PetscFunctionBegin; 7408 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7409 PetscValidLogicalCollectiveInt(mat,rbs,2); 7410 PetscValidLogicalCollectiveInt(mat,cbs,3); 7411 if (mat->ops->setblocksizes) { 7412 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7413 } 7414 if (mat->rmap->refcnt) { 7415 ISLocalToGlobalMapping l2g = NULL; 7416 PetscLayout nmap = NULL; 7417 7418 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7419 if (mat->rmap->mapping) { 7420 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7421 } 7422 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7423 mat->rmap = nmap; 7424 mat->rmap->mapping = l2g; 7425 } 7426 if (mat->cmap->refcnt) { 7427 ISLocalToGlobalMapping l2g = NULL; 7428 PetscLayout nmap = NULL; 7429 7430 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7431 if (mat->cmap->mapping) { 7432 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7433 } 7434 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7435 mat->cmap = nmap; 7436 mat->cmap->mapping = l2g; 7437 } 7438 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7439 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7440 PetscFunctionReturn(0); 7441 } 7442 7443 /*@ 7444 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7445 7446 Logically Collective on Mat 7447 7448 Input Parameters: 7449 + mat - the matrix 7450 . fromRow - matrix from which to copy row block size 7451 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7452 7453 Level: developer 7454 7455 Concepts: matrices^block size 7456 7457 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7458 @*/ 7459 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7460 { 7461 PetscErrorCode ierr; 7462 7463 PetscFunctionBegin; 7464 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7465 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7466 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7467 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7468 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7469 PetscFunctionReturn(0); 7470 } 7471 7472 /*@ 7473 MatResidual - Default routine to calculate the residual. 7474 7475 Collective on Mat and Vec 7476 7477 Input Parameters: 7478 + mat - the matrix 7479 . b - the right-hand-side 7480 - x - the approximate solution 7481 7482 Output Parameter: 7483 . r - location to store the residual 7484 7485 Level: developer 7486 7487 .keywords: MG, default, multigrid, residual 7488 7489 .seealso: PCMGSetResidual() 7490 @*/ 7491 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7492 { 7493 PetscErrorCode ierr; 7494 7495 PetscFunctionBegin; 7496 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7497 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7498 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7499 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7500 PetscValidType(mat,1); 7501 MatCheckPreallocated(mat,1); 7502 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7503 if (!mat->ops->residual) { 7504 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7505 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7506 } else { 7507 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7508 } 7509 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7510 PetscFunctionReturn(0); 7511 } 7512 7513 /*@C 7514 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7515 7516 Collective on Mat 7517 7518 Input Parameters: 7519 + mat - the matrix 7520 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7521 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7522 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7523 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7524 always used. 7525 7526 Output Parameters: 7527 + n - number of rows in the (possibly compressed) matrix 7528 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7529 . ja - the column indices 7530 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7531 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7532 7533 Level: developer 7534 7535 Notes: 7536 You CANNOT change any of the ia[] or ja[] values. 7537 7538 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7539 7540 Fortran Notes: 7541 In Fortran use 7542 $ 7543 $ PetscInt ia(1), ja(1) 7544 $ PetscOffset iia, jja 7545 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7546 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7547 7548 or 7549 $ 7550 $ PetscInt, pointer :: ia(:),ja(:) 7551 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7552 $ ! Access the ith and jth entries via ia(i) and ja(j) 7553 7554 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7555 @*/ 7556 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7557 { 7558 PetscErrorCode ierr; 7559 7560 PetscFunctionBegin; 7561 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7562 PetscValidType(mat,1); 7563 PetscValidIntPointer(n,5); 7564 if (ia) PetscValidIntPointer(ia,6); 7565 if (ja) PetscValidIntPointer(ja,7); 7566 PetscValidIntPointer(done,8); 7567 MatCheckPreallocated(mat,1); 7568 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7569 else { 7570 *done = PETSC_TRUE; 7571 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7572 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7573 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7574 } 7575 PetscFunctionReturn(0); 7576 } 7577 7578 /*@C 7579 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7580 7581 Collective on Mat 7582 7583 Input Parameters: 7584 + mat - the matrix 7585 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7586 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7587 symmetrized 7588 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7589 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7590 always used. 7591 . n - number of columns in the (possibly compressed) matrix 7592 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7593 - ja - the row indices 7594 7595 Output Parameters: 7596 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7597 7598 Level: developer 7599 7600 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7601 @*/ 7602 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7603 { 7604 PetscErrorCode ierr; 7605 7606 PetscFunctionBegin; 7607 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7608 PetscValidType(mat,1); 7609 PetscValidIntPointer(n,4); 7610 if (ia) PetscValidIntPointer(ia,5); 7611 if (ja) PetscValidIntPointer(ja,6); 7612 PetscValidIntPointer(done,7); 7613 MatCheckPreallocated(mat,1); 7614 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7615 else { 7616 *done = PETSC_TRUE; 7617 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7618 } 7619 PetscFunctionReturn(0); 7620 } 7621 7622 /*@C 7623 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7624 MatGetRowIJ(). 7625 7626 Collective on Mat 7627 7628 Input Parameters: 7629 + mat - the matrix 7630 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7631 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7632 symmetrized 7633 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7634 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7635 always used. 7636 . n - size of (possibly compressed) matrix 7637 . ia - the row pointers 7638 - ja - the column indices 7639 7640 Output Parameters: 7641 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7642 7643 Note: 7644 This routine zeros out n, ia, and ja. This is to prevent accidental 7645 us of the array after it has been restored. If you pass NULL, it will 7646 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7647 7648 Level: developer 7649 7650 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7651 @*/ 7652 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7653 { 7654 PetscErrorCode ierr; 7655 7656 PetscFunctionBegin; 7657 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7658 PetscValidType(mat,1); 7659 if (ia) PetscValidIntPointer(ia,6); 7660 if (ja) PetscValidIntPointer(ja,7); 7661 PetscValidIntPointer(done,8); 7662 MatCheckPreallocated(mat,1); 7663 7664 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7665 else { 7666 *done = PETSC_TRUE; 7667 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7668 if (n) *n = 0; 7669 if (ia) *ia = NULL; 7670 if (ja) *ja = NULL; 7671 } 7672 PetscFunctionReturn(0); 7673 } 7674 7675 /*@C 7676 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7677 MatGetColumnIJ(). 7678 7679 Collective on Mat 7680 7681 Input Parameters: 7682 + mat - the matrix 7683 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7684 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7685 symmetrized 7686 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7687 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7688 always used. 7689 7690 Output Parameters: 7691 + n - size of (possibly compressed) matrix 7692 . ia - the column pointers 7693 . ja - the row indices 7694 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7695 7696 Level: developer 7697 7698 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7699 @*/ 7700 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7701 { 7702 PetscErrorCode ierr; 7703 7704 PetscFunctionBegin; 7705 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7706 PetscValidType(mat,1); 7707 if (ia) PetscValidIntPointer(ia,5); 7708 if (ja) PetscValidIntPointer(ja,6); 7709 PetscValidIntPointer(done,7); 7710 MatCheckPreallocated(mat,1); 7711 7712 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7713 else { 7714 *done = PETSC_TRUE; 7715 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7716 if (n) *n = 0; 7717 if (ia) *ia = NULL; 7718 if (ja) *ja = NULL; 7719 } 7720 PetscFunctionReturn(0); 7721 } 7722 7723 /*@C 7724 MatColoringPatch -Used inside matrix coloring routines that 7725 use MatGetRowIJ() and/or MatGetColumnIJ(). 7726 7727 Collective on Mat 7728 7729 Input Parameters: 7730 + mat - the matrix 7731 . ncolors - max color value 7732 . n - number of entries in colorarray 7733 - colorarray - array indicating color for each column 7734 7735 Output Parameters: 7736 . iscoloring - coloring generated using colorarray information 7737 7738 Level: developer 7739 7740 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7741 7742 @*/ 7743 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7744 { 7745 PetscErrorCode ierr; 7746 7747 PetscFunctionBegin; 7748 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7749 PetscValidType(mat,1); 7750 PetscValidIntPointer(colorarray,4); 7751 PetscValidPointer(iscoloring,5); 7752 MatCheckPreallocated(mat,1); 7753 7754 if (!mat->ops->coloringpatch) { 7755 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7756 } else { 7757 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7758 } 7759 PetscFunctionReturn(0); 7760 } 7761 7762 7763 /*@ 7764 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7765 7766 Logically Collective on Mat 7767 7768 Input Parameter: 7769 . mat - the factored matrix to be reset 7770 7771 Notes: 7772 This routine should be used only with factored matrices formed by in-place 7773 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7774 format). This option can save memory, for example, when solving nonlinear 7775 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7776 ILU(0) preconditioner. 7777 7778 Note that one can specify in-place ILU(0) factorization by calling 7779 .vb 7780 PCType(pc,PCILU); 7781 PCFactorSeUseInPlace(pc); 7782 .ve 7783 or by using the options -pc_type ilu -pc_factor_in_place 7784 7785 In-place factorization ILU(0) can also be used as a local 7786 solver for the blocks within the block Jacobi or additive Schwarz 7787 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7788 for details on setting local solver options. 7789 7790 Most users should employ the simplified KSP interface for linear solvers 7791 instead of working directly with matrix algebra routines such as this. 7792 See, e.g., KSPCreate(). 7793 7794 Level: developer 7795 7796 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7797 7798 Concepts: matrices^unfactored 7799 7800 @*/ 7801 PetscErrorCode MatSetUnfactored(Mat mat) 7802 { 7803 PetscErrorCode ierr; 7804 7805 PetscFunctionBegin; 7806 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7807 PetscValidType(mat,1); 7808 MatCheckPreallocated(mat,1); 7809 mat->factortype = MAT_FACTOR_NONE; 7810 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7811 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7812 PetscFunctionReturn(0); 7813 } 7814 7815 /*MC 7816 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7817 7818 Synopsis: 7819 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7820 7821 Not collective 7822 7823 Input Parameter: 7824 . x - matrix 7825 7826 Output Parameters: 7827 + xx_v - the Fortran90 pointer to the array 7828 - ierr - error code 7829 7830 Example of Usage: 7831 .vb 7832 PetscScalar, pointer xx_v(:,:) 7833 .... 7834 call MatDenseGetArrayF90(x,xx_v,ierr) 7835 a = xx_v(3) 7836 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7837 .ve 7838 7839 Level: advanced 7840 7841 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7842 7843 Concepts: matrices^accessing array 7844 7845 M*/ 7846 7847 /*MC 7848 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7849 accessed with MatDenseGetArrayF90(). 7850 7851 Synopsis: 7852 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7853 7854 Not collective 7855 7856 Input Parameters: 7857 + x - matrix 7858 - xx_v - the Fortran90 pointer to the array 7859 7860 Output Parameter: 7861 . ierr - error code 7862 7863 Example of Usage: 7864 .vb 7865 PetscScalar, pointer xx_v(:,:) 7866 .... 7867 call MatDenseGetArrayF90(x,xx_v,ierr) 7868 a = xx_v(3) 7869 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7870 .ve 7871 7872 Level: advanced 7873 7874 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7875 7876 M*/ 7877 7878 7879 /*MC 7880 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7881 7882 Synopsis: 7883 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7884 7885 Not collective 7886 7887 Input Parameter: 7888 . x - matrix 7889 7890 Output Parameters: 7891 + xx_v - the Fortran90 pointer to the array 7892 - ierr - error code 7893 7894 Example of Usage: 7895 .vb 7896 PetscScalar, pointer xx_v(:) 7897 .... 7898 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7899 a = xx_v(3) 7900 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7901 .ve 7902 7903 Level: advanced 7904 7905 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7906 7907 Concepts: matrices^accessing array 7908 7909 M*/ 7910 7911 /*MC 7912 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7913 accessed with MatSeqAIJGetArrayF90(). 7914 7915 Synopsis: 7916 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7917 7918 Not collective 7919 7920 Input Parameters: 7921 + x - matrix 7922 - xx_v - the Fortran90 pointer to the array 7923 7924 Output Parameter: 7925 . ierr - error code 7926 7927 Example of Usage: 7928 .vb 7929 PetscScalar, pointer xx_v(:) 7930 .... 7931 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7932 a = xx_v(3) 7933 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7934 .ve 7935 7936 Level: advanced 7937 7938 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7939 7940 M*/ 7941 7942 7943 /*@ 7944 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7945 as the original matrix. 7946 7947 Collective on Mat 7948 7949 Input Parameters: 7950 + mat - the original matrix 7951 . isrow - parallel IS containing the rows this processor should obtain 7952 . 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. 7953 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7954 7955 Output Parameter: 7956 . newmat - the new submatrix, of the same type as the old 7957 7958 Level: advanced 7959 7960 Notes: 7961 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7962 7963 Some matrix types place restrictions on the row and column indices, such 7964 as that they be sorted or that they be equal to each other. 7965 7966 The index sets may not have duplicate entries. 7967 7968 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7969 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7970 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7971 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7972 you are finished using it. 7973 7974 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7975 the input matrix. 7976 7977 If iscol is NULL then all columns are obtained (not supported in Fortran). 7978 7979 Example usage: 7980 Consider the following 8x8 matrix with 34 non-zero values, that is 7981 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7982 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7983 as follows: 7984 7985 .vb 7986 1 2 0 | 0 3 0 | 0 4 7987 Proc0 0 5 6 | 7 0 0 | 8 0 7988 9 0 10 | 11 0 0 | 12 0 7989 ------------------------------------- 7990 13 0 14 | 15 16 17 | 0 0 7991 Proc1 0 18 0 | 19 20 21 | 0 0 7992 0 0 0 | 22 23 0 | 24 0 7993 ------------------------------------- 7994 Proc2 25 26 27 | 0 0 28 | 29 0 7995 30 0 0 | 31 32 33 | 0 34 7996 .ve 7997 7998 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7999 8000 .vb 8001 2 0 | 0 3 0 | 0 8002 Proc0 5 6 | 7 0 0 | 8 8003 ------------------------------- 8004 Proc1 18 0 | 19 20 21 | 0 8005 ------------------------------- 8006 Proc2 26 27 | 0 0 28 | 29 8007 0 0 | 31 32 33 | 0 8008 .ve 8009 8010 8011 Concepts: matrices^submatrices 8012 8013 .seealso: MatCreateSubMatrices() 8014 @*/ 8015 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8016 { 8017 PetscErrorCode ierr; 8018 PetscMPIInt size; 8019 Mat *local; 8020 IS iscoltmp; 8021 8022 PetscFunctionBegin; 8023 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8024 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8025 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8026 PetscValidPointer(newmat,5); 8027 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8028 PetscValidType(mat,1); 8029 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8030 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8031 8032 MatCheckPreallocated(mat,1); 8033 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8034 8035 if (!iscol || isrow == iscol) { 8036 PetscBool stride; 8037 PetscMPIInt grabentirematrix = 0,grab; 8038 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 8039 if (stride) { 8040 PetscInt first,step,n,rstart,rend; 8041 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 8042 if (step == 1) { 8043 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 8044 if (rstart == first) { 8045 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 8046 if (n == rend-rstart) { 8047 grabentirematrix = 1; 8048 } 8049 } 8050 } 8051 } 8052 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 8053 if (grab) { 8054 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 8055 if (cll == MAT_INITIAL_MATRIX) { 8056 *newmat = mat; 8057 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 8058 } 8059 PetscFunctionReturn(0); 8060 } 8061 } 8062 8063 if (!iscol) { 8064 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 8065 } else { 8066 iscoltmp = iscol; 8067 } 8068 8069 /* if original matrix is on just one processor then use submatrix generated */ 8070 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8071 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 8072 goto setproperties; 8073 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8074 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8075 *newmat = *local; 8076 ierr = PetscFree(local);CHKERRQ(ierr); 8077 goto setproperties; 8078 } else if (!mat->ops->createsubmatrix) { 8079 /* Create a new matrix type that implements the operation using the full matrix */ 8080 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8081 switch (cll) { 8082 case MAT_INITIAL_MATRIX: 8083 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8084 break; 8085 case MAT_REUSE_MATRIX: 8086 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8087 break; 8088 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8089 } 8090 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8091 goto setproperties; 8092 } 8093 8094 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8095 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8096 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8097 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8098 8099 /* Propagate symmetry information for diagonal blocks */ 8100 setproperties: 8101 if (isrow == iscoltmp) { 8102 if (mat->symmetric_set && mat->symmetric) { 8103 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8104 } 8105 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 8106 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8107 } 8108 if (mat->hermitian_set && mat->hermitian) { 8109 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 8110 } 8111 if (mat->spd_set && mat->spd) { 8112 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 8113 } 8114 } 8115 8116 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8117 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8118 PetscFunctionReturn(0); 8119 } 8120 8121 /*@ 8122 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8123 used during the assembly process to store values that belong to 8124 other processors. 8125 8126 Not Collective 8127 8128 Input Parameters: 8129 + mat - the matrix 8130 . size - the initial size of the stash. 8131 - bsize - the initial size of the block-stash(if used). 8132 8133 Options Database Keys: 8134 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8135 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8136 8137 Level: intermediate 8138 8139 Notes: 8140 The block-stash is used for values set with MatSetValuesBlocked() while 8141 the stash is used for values set with MatSetValues() 8142 8143 Run with the option -info and look for output of the form 8144 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8145 to determine the appropriate value, MM, to use for size and 8146 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8147 to determine the value, BMM to use for bsize 8148 8149 Concepts: stash^setting matrix size 8150 Concepts: matrices^stash 8151 8152 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8153 8154 @*/ 8155 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8156 { 8157 PetscErrorCode ierr; 8158 8159 PetscFunctionBegin; 8160 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8161 PetscValidType(mat,1); 8162 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8163 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8164 PetscFunctionReturn(0); 8165 } 8166 8167 /*@ 8168 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8169 the matrix 8170 8171 Neighbor-wise Collective on Mat 8172 8173 Input Parameters: 8174 + mat - the matrix 8175 . x,y - the vectors 8176 - w - where the result is stored 8177 8178 Level: intermediate 8179 8180 Notes: 8181 w may be the same vector as y. 8182 8183 This allows one to use either the restriction or interpolation (its transpose) 8184 matrix to do the interpolation 8185 8186 Concepts: interpolation 8187 8188 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8189 8190 @*/ 8191 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8192 { 8193 PetscErrorCode ierr; 8194 PetscInt M,N,Ny; 8195 8196 PetscFunctionBegin; 8197 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8198 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8199 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8200 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8201 PetscValidType(A,1); 8202 MatCheckPreallocated(A,1); 8203 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8204 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8205 if (M == Ny) { 8206 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8207 } else { 8208 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8209 } 8210 PetscFunctionReturn(0); 8211 } 8212 8213 /*@ 8214 MatInterpolate - y = A*x or A'*x depending on the shape of 8215 the matrix 8216 8217 Neighbor-wise Collective on Mat 8218 8219 Input Parameters: 8220 + mat - the matrix 8221 - x,y - the vectors 8222 8223 Level: intermediate 8224 8225 Notes: 8226 This allows one to use either the restriction or interpolation (its transpose) 8227 matrix to do the interpolation 8228 8229 Concepts: matrices^interpolation 8230 8231 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8232 8233 @*/ 8234 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8235 { 8236 PetscErrorCode ierr; 8237 PetscInt M,N,Ny; 8238 8239 PetscFunctionBegin; 8240 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8241 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8242 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8243 PetscValidType(A,1); 8244 MatCheckPreallocated(A,1); 8245 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8246 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8247 if (M == Ny) { 8248 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8249 } else { 8250 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8251 } 8252 PetscFunctionReturn(0); 8253 } 8254 8255 /*@ 8256 MatRestrict - y = A*x or A'*x 8257 8258 Neighbor-wise Collective on Mat 8259 8260 Input Parameters: 8261 + mat - the matrix 8262 - x,y - the vectors 8263 8264 Level: intermediate 8265 8266 Notes: 8267 This allows one to use either the restriction or interpolation (its transpose) 8268 matrix to do the restriction 8269 8270 Concepts: matrices^restriction 8271 8272 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8273 8274 @*/ 8275 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8276 { 8277 PetscErrorCode ierr; 8278 PetscInt M,N,Ny; 8279 8280 PetscFunctionBegin; 8281 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8282 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8283 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8284 PetscValidType(A,1); 8285 MatCheckPreallocated(A,1); 8286 8287 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8288 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8289 if (M == Ny) { 8290 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8291 } else { 8292 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8293 } 8294 PetscFunctionReturn(0); 8295 } 8296 8297 /*@ 8298 MatGetNullSpace - retrieves the null space of a matrix. 8299 8300 Logically Collective on Mat and MatNullSpace 8301 8302 Input Parameters: 8303 + mat - the matrix 8304 - nullsp - the null space object 8305 8306 Level: developer 8307 8308 Concepts: null space^attaching to matrix 8309 8310 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8311 @*/ 8312 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8313 { 8314 PetscFunctionBegin; 8315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8316 PetscValidPointer(nullsp,2); 8317 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8318 PetscFunctionReturn(0); 8319 } 8320 8321 /*@ 8322 MatSetNullSpace - attaches a null space to a matrix. 8323 8324 Logically Collective on Mat and MatNullSpace 8325 8326 Input Parameters: 8327 + mat - the matrix 8328 - nullsp - the null space object 8329 8330 Level: advanced 8331 8332 Notes: 8333 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8334 8335 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8336 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8337 8338 You can remove the null space by calling this routine with an nullsp of NULL 8339 8340 8341 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8342 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). 8343 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 8344 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 8345 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). 8346 8347 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8348 8349 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 8350 routine also automatically calls MatSetTransposeNullSpace(). 8351 8352 Concepts: null space^attaching to matrix 8353 8354 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8355 @*/ 8356 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8357 { 8358 PetscErrorCode ierr; 8359 8360 PetscFunctionBegin; 8361 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8362 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8363 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8364 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8365 mat->nullsp = nullsp; 8366 if (mat->symmetric_set && mat->symmetric) { 8367 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8368 } 8369 PetscFunctionReturn(0); 8370 } 8371 8372 /*@ 8373 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8374 8375 Logically Collective on Mat and MatNullSpace 8376 8377 Input Parameters: 8378 + mat - the matrix 8379 - nullsp - the null space object 8380 8381 Level: developer 8382 8383 Concepts: null space^attaching to matrix 8384 8385 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8386 @*/ 8387 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8388 { 8389 PetscFunctionBegin; 8390 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8391 PetscValidType(mat,1); 8392 PetscValidPointer(nullsp,2); 8393 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8394 PetscFunctionReturn(0); 8395 } 8396 8397 /*@ 8398 MatSetTransposeNullSpace - attaches a null space to a matrix. 8399 8400 Logically Collective on Mat and MatNullSpace 8401 8402 Input Parameters: 8403 + mat - the matrix 8404 - nullsp - the null space object 8405 8406 Level: advanced 8407 8408 Notes: 8409 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. 8410 You must also call MatSetNullSpace() 8411 8412 8413 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8414 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). 8415 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 8416 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 8417 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). 8418 8419 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8420 8421 Concepts: null space^attaching to matrix 8422 8423 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8424 @*/ 8425 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8426 { 8427 PetscErrorCode ierr; 8428 8429 PetscFunctionBegin; 8430 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8431 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8432 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8433 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8434 mat->transnullsp = nullsp; 8435 PetscFunctionReturn(0); 8436 } 8437 8438 /*@ 8439 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8440 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8441 8442 Logically Collective on Mat and MatNullSpace 8443 8444 Input Parameters: 8445 + mat - the matrix 8446 - nullsp - the null space object 8447 8448 Level: advanced 8449 8450 Notes: 8451 Overwrites any previous near null space that may have been attached 8452 8453 You can remove the null space by calling this routine with an nullsp of NULL 8454 8455 Concepts: null space^attaching to matrix 8456 8457 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8458 @*/ 8459 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8460 { 8461 PetscErrorCode ierr; 8462 8463 PetscFunctionBegin; 8464 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8465 PetscValidType(mat,1); 8466 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8467 MatCheckPreallocated(mat,1); 8468 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8469 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8470 mat->nearnullsp = nullsp; 8471 PetscFunctionReturn(0); 8472 } 8473 8474 /*@ 8475 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8476 8477 Not Collective 8478 8479 Input Parameters: 8480 . mat - the matrix 8481 8482 Output Parameters: 8483 . nullsp - the null space object, NULL if not set 8484 8485 Level: developer 8486 8487 Concepts: null space^attaching to matrix 8488 8489 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8490 @*/ 8491 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8492 { 8493 PetscFunctionBegin; 8494 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8495 PetscValidType(mat,1); 8496 PetscValidPointer(nullsp,2); 8497 MatCheckPreallocated(mat,1); 8498 *nullsp = mat->nearnullsp; 8499 PetscFunctionReturn(0); 8500 } 8501 8502 /*@C 8503 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8504 8505 Collective on Mat 8506 8507 Input Parameters: 8508 + mat - the matrix 8509 . row - row/column permutation 8510 . fill - expected fill factor >= 1.0 8511 - level - level of fill, for ICC(k) 8512 8513 Notes: 8514 Probably really in-place only when level of fill is zero, otherwise allocates 8515 new space to store factored matrix and deletes previous memory. 8516 8517 Most users should employ the simplified KSP interface for linear solvers 8518 instead of working directly with matrix algebra routines such as this. 8519 See, e.g., KSPCreate(). 8520 8521 Level: developer 8522 8523 Concepts: matrices^incomplete Cholesky factorization 8524 Concepts: Cholesky factorization 8525 8526 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8527 8528 Developer Note: fortran interface is not autogenerated as the f90 8529 interface defintion cannot be generated correctly [due to MatFactorInfo] 8530 8531 @*/ 8532 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8533 { 8534 PetscErrorCode ierr; 8535 8536 PetscFunctionBegin; 8537 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8538 PetscValidType(mat,1); 8539 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8540 PetscValidPointer(info,3); 8541 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8542 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8543 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8544 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8545 MatCheckPreallocated(mat,1); 8546 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8547 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8548 PetscFunctionReturn(0); 8549 } 8550 8551 /*@ 8552 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8553 ghosted ones. 8554 8555 Not Collective 8556 8557 Input Parameters: 8558 + mat - the matrix 8559 - diag = the diagonal values, including ghost ones 8560 8561 Level: developer 8562 8563 Notes: 8564 Works only for MPIAIJ and MPIBAIJ matrices 8565 8566 .seealso: MatDiagonalScale() 8567 @*/ 8568 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8569 { 8570 PetscErrorCode ierr; 8571 PetscMPIInt size; 8572 8573 PetscFunctionBegin; 8574 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8575 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8576 PetscValidType(mat,1); 8577 8578 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8579 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8580 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8581 if (size == 1) { 8582 PetscInt n,m; 8583 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8584 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8585 if (m == n) { 8586 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8587 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8588 } else { 8589 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8590 } 8591 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8592 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8593 PetscFunctionReturn(0); 8594 } 8595 8596 /*@ 8597 MatGetInertia - Gets the inertia from a factored matrix 8598 8599 Collective on Mat 8600 8601 Input Parameter: 8602 . mat - the matrix 8603 8604 Output Parameters: 8605 + nneg - number of negative eigenvalues 8606 . nzero - number of zero eigenvalues 8607 - npos - number of positive eigenvalues 8608 8609 Level: advanced 8610 8611 Notes: 8612 Matrix must have been factored by MatCholeskyFactor() 8613 8614 8615 @*/ 8616 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8617 { 8618 PetscErrorCode ierr; 8619 8620 PetscFunctionBegin; 8621 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8622 PetscValidType(mat,1); 8623 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8624 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8625 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8626 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8627 PetscFunctionReturn(0); 8628 } 8629 8630 /* ----------------------------------------------------------------*/ 8631 /*@C 8632 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8633 8634 Neighbor-wise Collective on Mat and Vecs 8635 8636 Input Parameters: 8637 + mat - the factored matrix 8638 - b - the right-hand-side vectors 8639 8640 Output Parameter: 8641 . x - the result vectors 8642 8643 Notes: 8644 The vectors b and x cannot be the same. I.e., one cannot 8645 call MatSolves(A,x,x). 8646 8647 Notes: 8648 Most users should employ the simplified KSP interface for linear solvers 8649 instead of working directly with matrix algebra routines such as this. 8650 See, e.g., KSPCreate(). 8651 8652 Level: developer 8653 8654 Concepts: matrices^triangular solves 8655 8656 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8657 @*/ 8658 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8659 { 8660 PetscErrorCode ierr; 8661 8662 PetscFunctionBegin; 8663 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8664 PetscValidType(mat,1); 8665 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8666 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8667 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8668 8669 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8670 MatCheckPreallocated(mat,1); 8671 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8672 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8673 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8674 PetscFunctionReturn(0); 8675 } 8676 8677 /*@ 8678 MatIsSymmetric - Test whether a matrix is symmetric 8679 8680 Collective on Mat 8681 8682 Input Parameter: 8683 + A - the matrix to test 8684 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8685 8686 Output Parameters: 8687 . flg - the result 8688 8689 Notes: 8690 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8691 8692 Level: intermediate 8693 8694 Concepts: matrix^symmetry 8695 8696 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8697 @*/ 8698 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8699 { 8700 PetscErrorCode ierr; 8701 8702 PetscFunctionBegin; 8703 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8704 PetscValidPointer(flg,2); 8705 8706 if (!A->symmetric_set) { 8707 if (!A->ops->issymmetric) { 8708 MatType mattype; 8709 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8710 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8711 } 8712 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8713 if (!tol) { 8714 A->symmetric_set = PETSC_TRUE; 8715 A->symmetric = *flg; 8716 if (A->symmetric) { 8717 A->structurally_symmetric_set = PETSC_TRUE; 8718 A->structurally_symmetric = PETSC_TRUE; 8719 } 8720 } 8721 } else if (A->symmetric) { 8722 *flg = PETSC_TRUE; 8723 } else if (!tol) { 8724 *flg = PETSC_FALSE; 8725 } else { 8726 if (!A->ops->issymmetric) { 8727 MatType mattype; 8728 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8729 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8730 } 8731 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8732 } 8733 PetscFunctionReturn(0); 8734 } 8735 8736 /*@ 8737 MatIsHermitian - Test whether a matrix is Hermitian 8738 8739 Collective on Mat 8740 8741 Input Parameter: 8742 + A - the matrix to test 8743 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8744 8745 Output Parameters: 8746 . flg - the result 8747 8748 Level: intermediate 8749 8750 Concepts: matrix^symmetry 8751 8752 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8753 MatIsSymmetricKnown(), MatIsSymmetric() 8754 @*/ 8755 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8756 { 8757 PetscErrorCode ierr; 8758 8759 PetscFunctionBegin; 8760 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8761 PetscValidPointer(flg,2); 8762 8763 if (!A->hermitian_set) { 8764 if (!A->ops->ishermitian) { 8765 MatType mattype; 8766 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8767 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8768 } 8769 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8770 if (!tol) { 8771 A->hermitian_set = PETSC_TRUE; 8772 A->hermitian = *flg; 8773 if (A->hermitian) { 8774 A->structurally_symmetric_set = PETSC_TRUE; 8775 A->structurally_symmetric = PETSC_TRUE; 8776 } 8777 } 8778 } else if (A->hermitian) { 8779 *flg = PETSC_TRUE; 8780 } else if (!tol) { 8781 *flg = PETSC_FALSE; 8782 } else { 8783 if (!A->ops->ishermitian) { 8784 MatType mattype; 8785 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8786 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8787 } 8788 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8789 } 8790 PetscFunctionReturn(0); 8791 } 8792 8793 /*@ 8794 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8795 8796 Not Collective 8797 8798 Input Parameter: 8799 . A - the matrix to check 8800 8801 Output Parameters: 8802 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8803 - flg - the result 8804 8805 Level: advanced 8806 8807 Concepts: matrix^symmetry 8808 8809 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8810 if you want it explicitly checked 8811 8812 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8813 @*/ 8814 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8815 { 8816 PetscFunctionBegin; 8817 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8818 PetscValidPointer(set,2); 8819 PetscValidPointer(flg,3); 8820 if (A->symmetric_set) { 8821 *set = PETSC_TRUE; 8822 *flg = A->symmetric; 8823 } else { 8824 *set = PETSC_FALSE; 8825 } 8826 PetscFunctionReturn(0); 8827 } 8828 8829 /*@ 8830 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8831 8832 Not Collective 8833 8834 Input Parameter: 8835 . A - the matrix to check 8836 8837 Output Parameters: 8838 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8839 - flg - the result 8840 8841 Level: advanced 8842 8843 Concepts: matrix^symmetry 8844 8845 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8846 if you want it explicitly checked 8847 8848 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8849 @*/ 8850 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8851 { 8852 PetscFunctionBegin; 8853 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8854 PetscValidPointer(set,2); 8855 PetscValidPointer(flg,3); 8856 if (A->hermitian_set) { 8857 *set = PETSC_TRUE; 8858 *flg = A->hermitian; 8859 } else { 8860 *set = PETSC_FALSE; 8861 } 8862 PetscFunctionReturn(0); 8863 } 8864 8865 /*@ 8866 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8867 8868 Collective on Mat 8869 8870 Input Parameter: 8871 . A - the matrix to test 8872 8873 Output Parameters: 8874 . flg - the result 8875 8876 Level: intermediate 8877 8878 Concepts: matrix^symmetry 8879 8880 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8881 @*/ 8882 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8883 { 8884 PetscErrorCode ierr; 8885 8886 PetscFunctionBegin; 8887 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8888 PetscValidPointer(flg,2); 8889 if (!A->structurally_symmetric_set) { 8890 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8891 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8892 8893 A->structurally_symmetric_set = PETSC_TRUE; 8894 } 8895 *flg = A->structurally_symmetric; 8896 PetscFunctionReturn(0); 8897 } 8898 8899 /*@ 8900 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8901 to be communicated to other processors during the MatAssemblyBegin/End() process 8902 8903 Not collective 8904 8905 Input Parameter: 8906 . vec - the vector 8907 8908 Output Parameters: 8909 + nstash - the size of the stash 8910 . reallocs - the number of additional mallocs incurred. 8911 . bnstash - the size of the block stash 8912 - breallocs - the number of additional mallocs incurred.in the block stash 8913 8914 Level: advanced 8915 8916 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8917 8918 @*/ 8919 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8920 { 8921 PetscErrorCode ierr; 8922 8923 PetscFunctionBegin; 8924 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8925 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8926 PetscFunctionReturn(0); 8927 } 8928 8929 /*@C 8930 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8931 parallel layout 8932 8933 Collective on Mat 8934 8935 Input Parameter: 8936 . mat - the matrix 8937 8938 Output Parameter: 8939 + right - (optional) vector that the matrix can be multiplied against 8940 - left - (optional) vector that the matrix vector product can be stored in 8941 8942 Notes: 8943 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(). 8944 8945 Notes: 8946 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8947 8948 Level: advanced 8949 8950 .seealso: MatCreate(), VecDestroy() 8951 @*/ 8952 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8953 { 8954 PetscErrorCode ierr; 8955 8956 PetscFunctionBegin; 8957 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8958 PetscValidType(mat,1); 8959 if (mat->ops->getvecs) { 8960 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8961 } else { 8962 PetscInt rbs,cbs; 8963 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8964 if (right) { 8965 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8966 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8967 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8968 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8969 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8970 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8971 } 8972 if (left) { 8973 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8974 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8975 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8976 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8977 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8978 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8979 } 8980 } 8981 PetscFunctionReturn(0); 8982 } 8983 8984 /*@C 8985 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8986 with default values. 8987 8988 Not Collective 8989 8990 Input Parameters: 8991 . info - the MatFactorInfo data structure 8992 8993 8994 Notes: 8995 The solvers are generally used through the KSP and PC objects, for example 8996 PCLU, PCILU, PCCHOLESKY, PCICC 8997 8998 Level: developer 8999 9000 .seealso: MatFactorInfo 9001 9002 Developer Note: fortran interface is not autogenerated as the f90 9003 interface defintion cannot be generated correctly [due to MatFactorInfo] 9004 9005 @*/ 9006 9007 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9008 { 9009 PetscErrorCode ierr; 9010 9011 PetscFunctionBegin; 9012 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 9013 PetscFunctionReturn(0); 9014 } 9015 9016 /*@ 9017 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9018 9019 Collective on Mat 9020 9021 Input Parameters: 9022 + mat - the factored matrix 9023 - is - the index set defining the Schur indices (0-based) 9024 9025 Notes: 9026 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9027 9028 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9029 9030 Level: developer 9031 9032 Concepts: 9033 9034 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 9035 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 9036 9037 @*/ 9038 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9039 { 9040 PetscErrorCode ierr,(*f)(Mat,IS); 9041 9042 PetscFunctionBegin; 9043 PetscValidType(mat,1); 9044 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9045 PetscValidType(is,2); 9046 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9047 PetscCheckSameComm(mat,1,is,2); 9048 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9049 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 9050 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"); 9051 if (mat->schur) { 9052 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 9053 } 9054 ierr = (*f)(mat,is);CHKERRQ(ierr); 9055 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9056 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 9057 PetscFunctionReturn(0); 9058 } 9059 9060 /*@ 9061 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9062 9063 Logically Collective on Mat 9064 9065 Input Parameters: 9066 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9067 . S - location where to return the Schur complement, can be NULL 9068 - status - the status of the Schur complement matrix, can be NULL 9069 9070 Notes: 9071 You must call MatFactorSetSchurIS() before calling this routine. 9072 9073 The routine provides a copy of the Schur matrix stored within the solver data structures. 9074 The caller must destroy the object when it is no longer needed. 9075 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9076 9077 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) 9078 9079 Developer Notes: 9080 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9081 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9082 9083 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9084 9085 Level: advanced 9086 9087 References: 9088 9089 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9090 @*/ 9091 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9092 { 9093 PetscErrorCode ierr; 9094 9095 PetscFunctionBegin; 9096 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9097 if (S) PetscValidPointer(S,2); 9098 if (status) PetscValidPointer(status,3); 9099 if (S) { 9100 PetscErrorCode (*f)(Mat,Mat*); 9101 9102 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9103 if (f) { 9104 ierr = (*f)(F,S);CHKERRQ(ierr); 9105 } else { 9106 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9107 } 9108 } 9109 if (status) *status = F->schur_status; 9110 PetscFunctionReturn(0); 9111 } 9112 9113 /*@ 9114 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9115 9116 Logically Collective on Mat 9117 9118 Input Parameters: 9119 + F - the factored matrix obtained by calling MatGetFactor() 9120 . *S - location where to return the Schur complement, can be NULL 9121 - status - the status of the Schur complement matrix, can be NULL 9122 9123 Notes: 9124 You must call MatFactorSetSchurIS() before calling this routine. 9125 9126 Schur complement mode is currently implemented for sequential matrices. 9127 The routine returns a the Schur Complement stored within the data strutures of the solver. 9128 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9129 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9130 9131 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9132 9133 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9134 9135 Level: advanced 9136 9137 References: 9138 9139 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9140 @*/ 9141 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9142 { 9143 PetscFunctionBegin; 9144 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9145 if (S) PetscValidPointer(S,2); 9146 if (status) PetscValidPointer(status,3); 9147 if (S) *S = F->schur; 9148 if (status) *status = F->schur_status; 9149 PetscFunctionReturn(0); 9150 } 9151 9152 /*@ 9153 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9154 9155 Logically Collective on Mat 9156 9157 Input Parameters: 9158 + F - the factored matrix obtained by calling MatGetFactor() 9159 . *S - location where the Schur complement is stored 9160 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9161 9162 Notes: 9163 9164 Level: advanced 9165 9166 References: 9167 9168 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9169 @*/ 9170 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9171 { 9172 PetscErrorCode ierr; 9173 9174 PetscFunctionBegin; 9175 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9176 if (S) { 9177 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9178 *S = NULL; 9179 } 9180 F->schur_status = status; 9181 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9182 PetscFunctionReturn(0); 9183 } 9184 9185 /*@ 9186 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9187 9188 Logically Collective on Mat 9189 9190 Input Parameters: 9191 + F - the factored matrix obtained by calling MatGetFactor() 9192 . rhs - location where the right hand side of the Schur complement system is stored 9193 - sol - location where the solution of the Schur complement system has to be returned 9194 9195 Notes: 9196 The sizes of the vectors should match the size of the Schur complement 9197 9198 Must be called after MatFactorSetSchurIS() 9199 9200 Level: advanced 9201 9202 References: 9203 9204 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9205 @*/ 9206 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9207 { 9208 PetscErrorCode ierr; 9209 9210 PetscFunctionBegin; 9211 PetscValidType(F,1); 9212 PetscValidType(rhs,2); 9213 PetscValidType(sol,3); 9214 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9215 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9216 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9217 PetscCheckSameComm(F,1,rhs,2); 9218 PetscCheckSameComm(F,1,sol,3); 9219 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9220 switch (F->schur_status) { 9221 case MAT_FACTOR_SCHUR_FACTORED: 9222 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9223 break; 9224 case MAT_FACTOR_SCHUR_INVERTED: 9225 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9226 break; 9227 default: 9228 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9229 break; 9230 } 9231 PetscFunctionReturn(0); 9232 } 9233 9234 /*@ 9235 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9236 9237 Logically Collective on Mat 9238 9239 Input Parameters: 9240 + F - the factored matrix obtained by calling MatGetFactor() 9241 . rhs - location where the right hand side of the Schur complement system is stored 9242 - sol - location where the solution of the Schur complement system has to be returned 9243 9244 Notes: 9245 The sizes of the vectors should match the size of the Schur complement 9246 9247 Must be called after MatFactorSetSchurIS() 9248 9249 Level: advanced 9250 9251 References: 9252 9253 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9254 @*/ 9255 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9256 { 9257 PetscErrorCode ierr; 9258 9259 PetscFunctionBegin; 9260 PetscValidType(F,1); 9261 PetscValidType(rhs,2); 9262 PetscValidType(sol,3); 9263 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9264 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9265 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9266 PetscCheckSameComm(F,1,rhs,2); 9267 PetscCheckSameComm(F,1,sol,3); 9268 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9269 switch (F->schur_status) { 9270 case MAT_FACTOR_SCHUR_FACTORED: 9271 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9272 break; 9273 case MAT_FACTOR_SCHUR_INVERTED: 9274 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9275 break; 9276 default: 9277 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9278 break; 9279 } 9280 PetscFunctionReturn(0); 9281 } 9282 9283 /*@ 9284 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9285 9286 Logically Collective on Mat 9287 9288 Input Parameters: 9289 + F - the factored matrix obtained by calling MatGetFactor() 9290 9291 Notes: 9292 Must be called after MatFactorSetSchurIS(). 9293 9294 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9295 9296 Level: advanced 9297 9298 References: 9299 9300 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9301 @*/ 9302 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9303 { 9304 PetscErrorCode ierr; 9305 9306 PetscFunctionBegin; 9307 PetscValidType(F,1); 9308 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9309 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9310 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9311 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9312 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9313 PetscFunctionReturn(0); 9314 } 9315 9316 /*@ 9317 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9318 9319 Logically Collective on Mat 9320 9321 Input Parameters: 9322 + F - the factored matrix obtained by calling MatGetFactor() 9323 9324 Notes: 9325 Must be called after MatFactorSetSchurIS(). 9326 9327 Level: advanced 9328 9329 References: 9330 9331 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9332 @*/ 9333 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9334 { 9335 PetscErrorCode ierr; 9336 9337 PetscFunctionBegin; 9338 PetscValidType(F,1); 9339 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9340 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9341 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9342 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9343 PetscFunctionReturn(0); 9344 } 9345 9346 /*@ 9347 MatPtAP - Creates the matrix product C = P^T * A * P 9348 9349 Neighbor-wise Collective on Mat 9350 9351 Input Parameters: 9352 + A - the matrix 9353 . P - the projection matrix 9354 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9355 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9356 if the result is a dense matrix this is irrelevent 9357 9358 Output Parameters: 9359 . C - the product matrix 9360 9361 Notes: 9362 C will be created and must be destroyed by the user with MatDestroy(). 9363 9364 This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes 9365 which inherit from AIJ. 9366 9367 Level: intermediate 9368 9369 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9370 @*/ 9371 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9372 { 9373 PetscErrorCode ierr; 9374 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9375 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9376 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9377 PetscBool sametype; 9378 9379 PetscFunctionBegin; 9380 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9381 PetscValidType(A,1); 9382 MatCheckPreallocated(A,1); 9383 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9384 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9385 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9386 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9387 PetscValidType(P,2); 9388 MatCheckPreallocated(P,2); 9389 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9390 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9391 9392 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); 9393 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); 9394 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9395 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9396 9397 if (scall == MAT_REUSE_MATRIX) { 9398 PetscValidPointer(*C,5); 9399 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9400 9401 if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX"); 9402 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9403 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9404 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9405 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9406 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9407 PetscFunctionReturn(0); 9408 } 9409 9410 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9411 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9412 9413 fA = A->ops->ptap; 9414 fP = P->ops->ptap; 9415 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9416 if (fP == fA && sametype) { 9417 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9418 ptap = fA; 9419 } else { 9420 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9421 char ptapname[256]; 9422 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9423 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9424 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9425 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9426 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9427 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9428 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); 9429 } 9430 9431 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9432 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9433 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9434 if (A->symmetric_set && A->symmetric) { 9435 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9436 } 9437 PetscFunctionReturn(0); 9438 } 9439 9440 /*@ 9441 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9442 9443 Neighbor-wise Collective on Mat 9444 9445 Input Parameters: 9446 + A - the matrix 9447 - P - the projection matrix 9448 9449 Output Parameters: 9450 . C - the product matrix 9451 9452 Notes: 9453 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9454 the user using MatDeatroy(). 9455 9456 This routine is currently only implemented for pairs of AIJ matrices and classes 9457 which inherit from AIJ. C will be of type MATAIJ. 9458 9459 Level: intermediate 9460 9461 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9462 @*/ 9463 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9464 { 9465 PetscErrorCode ierr; 9466 9467 PetscFunctionBegin; 9468 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9469 PetscValidType(A,1); 9470 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9471 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9472 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9473 PetscValidType(P,2); 9474 MatCheckPreallocated(P,2); 9475 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9476 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9477 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9478 PetscValidType(C,3); 9479 MatCheckPreallocated(C,3); 9480 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9481 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); 9482 if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9483 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9484 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); 9485 MatCheckPreallocated(A,1); 9486 9487 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9488 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9489 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9490 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9491 PetscFunctionReturn(0); 9492 } 9493 9494 /*@ 9495 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9496 9497 Neighbor-wise Collective on Mat 9498 9499 Input Parameters: 9500 + A - the matrix 9501 - P - the projection matrix 9502 9503 Output Parameters: 9504 . C - the (i,j) structure of the product matrix 9505 9506 Notes: 9507 C will be created and must be destroyed by the user with MatDestroy(). 9508 9509 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9510 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9511 this (i,j) structure by calling MatPtAPNumeric(). 9512 9513 Level: intermediate 9514 9515 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9516 @*/ 9517 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9518 { 9519 PetscErrorCode ierr; 9520 9521 PetscFunctionBegin; 9522 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9523 PetscValidType(A,1); 9524 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9525 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9526 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9527 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9528 PetscValidType(P,2); 9529 MatCheckPreallocated(P,2); 9530 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9531 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9532 PetscValidPointer(C,3); 9533 9534 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); 9535 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); 9536 MatCheckPreallocated(A,1); 9537 9538 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9539 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9540 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9541 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9542 9543 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9544 PetscFunctionReturn(0); 9545 } 9546 9547 /*@ 9548 MatRARt - Creates the matrix product C = R * A * R^T 9549 9550 Neighbor-wise Collective on Mat 9551 9552 Input Parameters: 9553 + A - the matrix 9554 . R - the projection matrix 9555 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9556 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9557 if the result is a dense matrix this is irrelevent 9558 9559 Output Parameters: 9560 . C - the product matrix 9561 9562 Notes: 9563 C will be created and must be destroyed by the user with MatDestroy(). 9564 9565 This routine is currently only implemented for pairs of AIJ matrices and classes 9566 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9567 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9568 We recommend using MatPtAP(). 9569 9570 Level: intermediate 9571 9572 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9573 @*/ 9574 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9575 { 9576 PetscErrorCode ierr; 9577 9578 PetscFunctionBegin; 9579 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9580 PetscValidType(A,1); 9581 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9582 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9583 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9584 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9585 PetscValidType(R,2); 9586 MatCheckPreallocated(R,2); 9587 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9588 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9589 PetscValidPointer(C,3); 9590 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); 9591 9592 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9593 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9594 MatCheckPreallocated(A,1); 9595 9596 if (!A->ops->rart) { 9597 Mat Rt; 9598 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9599 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9600 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9601 PetscFunctionReturn(0); 9602 } 9603 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9604 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9605 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9606 PetscFunctionReturn(0); 9607 } 9608 9609 /*@ 9610 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9611 9612 Neighbor-wise Collective on Mat 9613 9614 Input Parameters: 9615 + A - the matrix 9616 - R - the projection matrix 9617 9618 Output Parameters: 9619 . C - the product matrix 9620 9621 Notes: 9622 C must have been created by calling MatRARtSymbolic and must be destroyed by 9623 the user using MatDestroy(). 9624 9625 This routine is currently only implemented for pairs of AIJ matrices and classes 9626 which inherit from AIJ. C will be of type MATAIJ. 9627 9628 Level: intermediate 9629 9630 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9631 @*/ 9632 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9633 { 9634 PetscErrorCode ierr; 9635 9636 PetscFunctionBegin; 9637 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9638 PetscValidType(A,1); 9639 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9640 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9641 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9642 PetscValidType(R,2); 9643 MatCheckPreallocated(R,2); 9644 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9645 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9646 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9647 PetscValidType(C,3); 9648 MatCheckPreallocated(C,3); 9649 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9650 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); 9651 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); 9652 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); 9653 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); 9654 MatCheckPreallocated(A,1); 9655 9656 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9657 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9658 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9659 PetscFunctionReturn(0); 9660 } 9661 9662 /*@ 9663 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9664 9665 Neighbor-wise Collective on Mat 9666 9667 Input Parameters: 9668 + A - the matrix 9669 - R - the projection matrix 9670 9671 Output Parameters: 9672 . C - the (i,j) structure of the product matrix 9673 9674 Notes: 9675 C will be created and must be destroyed by the user with MatDestroy(). 9676 9677 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9678 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9679 this (i,j) structure by calling MatRARtNumeric(). 9680 9681 Level: intermediate 9682 9683 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9684 @*/ 9685 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9686 { 9687 PetscErrorCode ierr; 9688 9689 PetscFunctionBegin; 9690 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9691 PetscValidType(A,1); 9692 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9693 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9694 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9695 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9696 PetscValidType(R,2); 9697 MatCheckPreallocated(R,2); 9698 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9699 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9700 PetscValidPointer(C,3); 9701 9702 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); 9703 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); 9704 MatCheckPreallocated(A,1); 9705 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9706 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9707 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9708 9709 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9710 PetscFunctionReturn(0); 9711 } 9712 9713 /*@ 9714 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9715 9716 Neighbor-wise Collective on Mat 9717 9718 Input Parameters: 9719 + A - the left matrix 9720 . B - the right matrix 9721 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9722 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9723 if the result is a dense matrix this is irrelevent 9724 9725 Output Parameters: 9726 . C - the product matrix 9727 9728 Notes: 9729 Unless scall is MAT_REUSE_MATRIX C will be created. 9730 9731 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 9732 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9733 9734 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9735 actually needed. 9736 9737 If you have many matrices with the same non-zero structure to multiply, you 9738 should either 9739 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9740 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9741 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 9742 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9743 9744 Level: intermediate 9745 9746 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9747 @*/ 9748 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9749 { 9750 PetscErrorCode ierr; 9751 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9752 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9753 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9754 9755 PetscFunctionBegin; 9756 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9757 PetscValidType(A,1); 9758 MatCheckPreallocated(A,1); 9759 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9760 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9761 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9762 PetscValidType(B,2); 9763 MatCheckPreallocated(B,2); 9764 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9765 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9766 PetscValidPointer(C,3); 9767 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9768 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); 9769 if (scall == MAT_REUSE_MATRIX) { 9770 PetscValidPointer(*C,5); 9771 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9772 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9773 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9774 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9775 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9776 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9777 PetscFunctionReturn(0); 9778 } 9779 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9780 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9781 9782 fA = A->ops->matmult; 9783 fB = B->ops->matmult; 9784 if (fB == fA) { 9785 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9786 mult = fB; 9787 } else { 9788 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9789 char multname[256]; 9790 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9791 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9792 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9793 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9794 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9795 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9796 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); 9797 } 9798 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9799 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9800 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9801 PetscFunctionReturn(0); 9802 } 9803 9804 /*@ 9805 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9806 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9807 9808 Neighbor-wise Collective on Mat 9809 9810 Input Parameters: 9811 + A - the left matrix 9812 . B - the right matrix 9813 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9814 if C is a dense matrix this is irrelevent 9815 9816 Output Parameters: 9817 . C - the product matrix 9818 9819 Notes: 9820 Unless scall is MAT_REUSE_MATRIX C will be created. 9821 9822 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9823 actually needed. 9824 9825 This routine is currently implemented for 9826 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9827 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9828 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9829 9830 Level: intermediate 9831 9832 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9833 We should incorporate them into PETSc. 9834 9835 .seealso: MatMatMult(), MatMatMultNumeric() 9836 @*/ 9837 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9838 { 9839 PetscErrorCode ierr; 9840 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9841 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9842 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9843 9844 PetscFunctionBegin; 9845 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9846 PetscValidType(A,1); 9847 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9848 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9849 9850 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9851 PetscValidType(B,2); 9852 MatCheckPreallocated(B,2); 9853 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9854 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9855 PetscValidPointer(C,3); 9856 9857 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); 9858 if (fill == PETSC_DEFAULT) fill = 2.0; 9859 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9860 MatCheckPreallocated(A,1); 9861 9862 Asymbolic = A->ops->matmultsymbolic; 9863 Bsymbolic = B->ops->matmultsymbolic; 9864 if (Asymbolic == Bsymbolic) { 9865 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9866 symbolic = Bsymbolic; 9867 } else { /* dispatch based on the type of A and B */ 9868 char symbolicname[256]; 9869 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9870 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9871 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9872 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9873 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9874 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9875 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); 9876 } 9877 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9878 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9879 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9880 PetscFunctionReturn(0); 9881 } 9882 9883 /*@ 9884 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9885 Call this routine after first calling MatMatMultSymbolic(). 9886 9887 Neighbor-wise Collective on Mat 9888 9889 Input Parameters: 9890 + A - the left matrix 9891 - B - the right matrix 9892 9893 Output Parameters: 9894 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9895 9896 Notes: 9897 C must have been created with MatMatMultSymbolic(). 9898 9899 This routine is currently implemented for 9900 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9901 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9902 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9903 9904 Level: intermediate 9905 9906 .seealso: MatMatMult(), MatMatMultSymbolic() 9907 @*/ 9908 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9909 { 9910 PetscErrorCode ierr; 9911 9912 PetscFunctionBegin; 9913 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9914 PetscFunctionReturn(0); 9915 } 9916 9917 /*@ 9918 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9919 9920 Neighbor-wise Collective on Mat 9921 9922 Input Parameters: 9923 + A - the left matrix 9924 . B - the right matrix 9925 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9926 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9927 9928 Output Parameters: 9929 . C - the product matrix 9930 9931 Notes: 9932 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9933 9934 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9935 9936 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9937 actually needed. 9938 9939 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9940 and for pairs of MPIDense matrices. 9941 9942 Options Database Keys: 9943 + -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9944 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9945 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9946 9947 Level: intermediate 9948 9949 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9950 @*/ 9951 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9952 { 9953 PetscErrorCode ierr; 9954 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9955 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9956 9957 PetscFunctionBegin; 9958 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9959 PetscValidType(A,1); 9960 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9961 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9962 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9963 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9964 PetscValidType(B,2); 9965 MatCheckPreallocated(B,2); 9966 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9967 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9968 PetscValidPointer(C,3); 9969 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); 9970 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9971 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9972 MatCheckPreallocated(A,1); 9973 9974 fA = A->ops->mattransposemult; 9975 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9976 fB = B->ops->mattransposemult; 9977 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9978 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); 9979 9980 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9981 if (scall == MAT_INITIAL_MATRIX) { 9982 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9983 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9984 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9985 } 9986 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9987 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9988 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9989 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9990 PetscFunctionReturn(0); 9991 } 9992 9993 /*@ 9994 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9995 9996 Neighbor-wise Collective on Mat 9997 9998 Input Parameters: 9999 + A - the left matrix 10000 . B - the right matrix 10001 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10002 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 10003 10004 Output Parameters: 10005 . C - the product matrix 10006 10007 Notes: 10008 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 10009 10010 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 10011 10012 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10013 actually needed. 10014 10015 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10016 which inherit from SeqAIJ. C will be of same type as the input matrices. 10017 10018 Level: intermediate 10019 10020 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 10021 @*/ 10022 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10023 { 10024 PetscErrorCode ierr; 10025 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 10026 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 10027 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 10028 10029 PetscFunctionBegin; 10030 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10031 PetscValidType(A,1); 10032 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10033 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10034 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10035 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10036 PetscValidType(B,2); 10037 MatCheckPreallocated(B,2); 10038 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10039 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10040 PetscValidPointer(C,3); 10041 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); 10042 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10043 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 10044 MatCheckPreallocated(A,1); 10045 10046 fA = A->ops->transposematmult; 10047 fB = B->ops->transposematmult; 10048 if (fB==fA) { 10049 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10050 transposematmult = fA; 10051 } else { 10052 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 10053 char multname[256]; 10054 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 10055 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10056 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10057 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10058 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 10059 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 10060 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); 10061 } 10062 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10063 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 10064 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10065 PetscFunctionReturn(0); 10066 } 10067 10068 /*@ 10069 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10070 10071 Neighbor-wise Collective on Mat 10072 10073 Input Parameters: 10074 + A - the left matrix 10075 . B - the middle matrix 10076 . C - the right matrix 10077 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10078 - 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 10079 if the result is a dense matrix this is irrelevent 10080 10081 Output Parameters: 10082 . D - the product matrix 10083 10084 Notes: 10085 Unless scall is MAT_REUSE_MATRIX D will be created. 10086 10087 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10088 10089 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10090 actually needed. 10091 10092 If you have many matrices with the same non-zero structure to multiply, you 10093 should use MAT_REUSE_MATRIX in all calls but the first or 10094 10095 Level: intermediate 10096 10097 .seealso: MatMatMult, MatPtAP() 10098 @*/ 10099 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10100 { 10101 PetscErrorCode ierr; 10102 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10103 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10104 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10105 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 10106 10107 PetscFunctionBegin; 10108 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10109 PetscValidType(A,1); 10110 MatCheckPreallocated(A,1); 10111 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10112 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10113 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10114 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10115 PetscValidType(B,2); 10116 MatCheckPreallocated(B,2); 10117 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10118 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10119 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10120 PetscValidPointer(C,3); 10121 MatCheckPreallocated(C,3); 10122 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10123 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10124 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); 10125 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); 10126 if (scall == MAT_REUSE_MATRIX) { 10127 PetscValidPointer(*D,6); 10128 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 10129 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10130 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10131 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10132 PetscFunctionReturn(0); 10133 } 10134 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10135 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 10136 10137 fA = A->ops->matmatmult; 10138 fB = B->ops->matmatmult; 10139 fC = C->ops->matmatmult; 10140 if (fA == fB && fA == fC) { 10141 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10142 mult = fA; 10143 } else { 10144 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 10145 char multname[256]; 10146 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 10147 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10148 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10149 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10150 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10151 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 10152 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 10153 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 10154 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); 10155 } 10156 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10157 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10158 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10159 PetscFunctionReturn(0); 10160 } 10161 10162 /*@ 10163 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10164 10165 Collective on Mat 10166 10167 Input Parameters: 10168 + mat - the matrix 10169 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10170 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10171 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10172 10173 Output Parameter: 10174 . matredundant - redundant matrix 10175 10176 Notes: 10177 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10178 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10179 10180 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10181 calling it. 10182 10183 Level: advanced 10184 10185 Concepts: subcommunicator 10186 Concepts: duplicate matrix 10187 10188 .seealso: MatDestroy() 10189 @*/ 10190 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10191 { 10192 PetscErrorCode ierr; 10193 MPI_Comm comm; 10194 PetscMPIInt size; 10195 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10196 Mat_Redundant *redund=NULL; 10197 PetscSubcomm psubcomm=NULL; 10198 MPI_Comm subcomm_in=subcomm; 10199 Mat *matseq; 10200 IS isrow,iscol; 10201 PetscBool newsubcomm=PETSC_FALSE; 10202 10203 PetscFunctionBegin; 10204 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10205 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10206 PetscValidPointer(*matredundant,5); 10207 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10208 } 10209 10210 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10211 if (size == 1 || nsubcomm == 1) { 10212 if (reuse == MAT_INITIAL_MATRIX) { 10213 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10214 } else { 10215 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"); 10216 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10217 } 10218 PetscFunctionReturn(0); 10219 } 10220 10221 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10222 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10223 MatCheckPreallocated(mat,1); 10224 10225 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10226 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10227 /* create psubcomm, then get subcomm */ 10228 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10229 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10230 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10231 10232 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10233 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10234 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10235 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10236 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10237 newsubcomm = PETSC_TRUE; 10238 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10239 } 10240 10241 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10242 if (reuse == MAT_INITIAL_MATRIX) { 10243 mloc_sub = PETSC_DECIDE; 10244 nloc_sub = PETSC_DECIDE; 10245 if (bs < 1) { 10246 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10247 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10248 } else { 10249 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10250 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10251 } 10252 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10253 rstart = rend - mloc_sub; 10254 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10255 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10256 } else { /* reuse == MAT_REUSE_MATRIX */ 10257 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"); 10258 /* retrieve subcomm */ 10259 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10260 redund = (*matredundant)->redundant; 10261 isrow = redund->isrow; 10262 iscol = redund->iscol; 10263 matseq = redund->matseq; 10264 } 10265 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10266 10267 /* get matredundant over subcomm */ 10268 if (reuse == MAT_INITIAL_MATRIX) { 10269 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10270 10271 /* create a supporting struct and attach it to C for reuse */ 10272 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10273 (*matredundant)->redundant = redund; 10274 redund->isrow = isrow; 10275 redund->iscol = iscol; 10276 redund->matseq = matseq; 10277 if (newsubcomm) { 10278 redund->subcomm = subcomm; 10279 } else { 10280 redund->subcomm = MPI_COMM_NULL; 10281 } 10282 } else { 10283 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10284 } 10285 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10286 PetscFunctionReturn(0); 10287 } 10288 10289 /*@C 10290 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10291 a given 'mat' object. Each submatrix can span multiple procs. 10292 10293 Collective on Mat 10294 10295 Input Parameters: 10296 + mat - the matrix 10297 . subcomm - the subcommunicator obtained by com_split(comm) 10298 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10299 10300 Output Parameter: 10301 . subMat - 'parallel submatrices each spans a given subcomm 10302 10303 Notes: 10304 The submatrix partition across processors is dictated by 'subComm' a 10305 communicator obtained by com_split(comm). The comm_split 10306 is not restriced to be grouped with consecutive original ranks. 10307 10308 Due the comm_split() usage, the parallel layout of the submatrices 10309 map directly to the layout of the original matrix [wrt the local 10310 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10311 into the 'DiagonalMat' of the subMat, hence it is used directly from 10312 the subMat. However the offDiagMat looses some columns - and this is 10313 reconstructed with MatSetValues() 10314 10315 Level: advanced 10316 10317 Concepts: subcommunicator 10318 Concepts: submatrices 10319 10320 .seealso: MatCreateSubMatrices() 10321 @*/ 10322 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10323 { 10324 PetscErrorCode ierr; 10325 PetscMPIInt commsize,subCommSize; 10326 10327 PetscFunctionBegin; 10328 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10329 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10330 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10331 10332 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"); 10333 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10334 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10335 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10336 PetscFunctionReturn(0); 10337 } 10338 10339 /*@ 10340 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10341 10342 Not Collective 10343 10344 Input Arguments: 10345 mat - matrix to extract local submatrix from 10346 isrow - local row indices for submatrix 10347 iscol - local column indices for submatrix 10348 10349 Output Arguments: 10350 submat - the submatrix 10351 10352 Level: intermediate 10353 10354 Notes: 10355 The submat should be returned with MatRestoreLocalSubMatrix(). 10356 10357 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10358 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10359 10360 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10361 MatSetValuesBlockedLocal() will also be implemented. 10362 10363 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10364 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10365 10366 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10367 @*/ 10368 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10369 { 10370 PetscErrorCode ierr; 10371 10372 PetscFunctionBegin; 10373 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10374 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10375 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10376 PetscCheckSameComm(isrow,2,iscol,3); 10377 PetscValidPointer(submat,4); 10378 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10379 10380 if (mat->ops->getlocalsubmatrix) { 10381 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10382 } else { 10383 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10384 } 10385 PetscFunctionReturn(0); 10386 } 10387 10388 /*@ 10389 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10390 10391 Not Collective 10392 10393 Input Arguments: 10394 mat - matrix to extract local submatrix from 10395 isrow - local row indices for submatrix 10396 iscol - local column indices for submatrix 10397 submat - the submatrix 10398 10399 Level: intermediate 10400 10401 .seealso: MatGetLocalSubMatrix() 10402 @*/ 10403 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10404 { 10405 PetscErrorCode ierr; 10406 10407 PetscFunctionBegin; 10408 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10409 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10410 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10411 PetscCheckSameComm(isrow,2,iscol,3); 10412 PetscValidPointer(submat,4); 10413 if (*submat) { 10414 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10415 } 10416 10417 if (mat->ops->restorelocalsubmatrix) { 10418 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10419 } else { 10420 ierr = MatDestroy(submat);CHKERRQ(ierr); 10421 } 10422 *submat = NULL; 10423 PetscFunctionReturn(0); 10424 } 10425 10426 /* --------------------------------------------------------*/ 10427 /*@ 10428 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10429 10430 Collective on Mat 10431 10432 Input Parameter: 10433 . mat - the matrix 10434 10435 Output Parameter: 10436 . is - if any rows have zero diagonals this contains the list of them 10437 10438 Level: developer 10439 10440 Concepts: matrix-vector product 10441 10442 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10443 @*/ 10444 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10445 { 10446 PetscErrorCode ierr; 10447 10448 PetscFunctionBegin; 10449 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10450 PetscValidType(mat,1); 10451 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10452 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10453 10454 if (!mat->ops->findzerodiagonals) { 10455 Vec diag; 10456 const PetscScalar *a; 10457 PetscInt *rows; 10458 PetscInt rStart, rEnd, r, nrow = 0; 10459 10460 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10461 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10462 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10463 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10464 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10465 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10466 nrow = 0; 10467 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10468 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10469 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10470 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10471 } else { 10472 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10473 } 10474 PetscFunctionReturn(0); 10475 } 10476 10477 /*@ 10478 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10479 10480 Collective on Mat 10481 10482 Input Parameter: 10483 . mat - the matrix 10484 10485 Output Parameter: 10486 . is - contains the list of rows with off block diagonal entries 10487 10488 Level: developer 10489 10490 Concepts: matrix-vector product 10491 10492 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10493 @*/ 10494 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10495 { 10496 PetscErrorCode ierr; 10497 10498 PetscFunctionBegin; 10499 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10500 PetscValidType(mat,1); 10501 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10502 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10503 10504 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10505 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10506 PetscFunctionReturn(0); 10507 } 10508 10509 /*@C 10510 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10511 10512 Collective on Mat 10513 10514 Input Parameters: 10515 . mat - the matrix 10516 10517 Output Parameters: 10518 . values - the block inverses in column major order (FORTRAN-like) 10519 10520 Note: 10521 This routine is not available from Fortran. 10522 10523 Level: advanced 10524 10525 .seealso: MatInvertBockDiagonalMat 10526 @*/ 10527 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10528 { 10529 PetscErrorCode ierr; 10530 10531 PetscFunctionBegin; 10532 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10533 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10534 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10535 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10536 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10537 PetscFunctionReturn(0); 10538 } 10539 10540 /*@C 10541 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10542 10543 Collective on Mat 10544 10545 Input Parameters: 10546 + mat - the matrix 10547 . nblocks - the number of blocks 10548 - bsizes - the size of each block 10549 10550 Output Parameters: 10551 . values - the block inverses in column major order (FORTRAN-like) 10552 10553 Note: 10554 This routine is not available from Fortran. 10555 10556 Level: advanced 10557 10558 .seealso: MatInvertBockDiagonal() 10559 @*/ 10560 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10561 { 10562 PetscErrorCode ierr; 10563 10564 PetscFunctionBegin; 10565 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10566 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10567 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10568 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10569 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10570 PetscFunctionReturn(0); 10571 } 10572 10573 /*@ 10574 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10575 10576 Collective on Mat 10577 10578 Input Parameters: 10579 . A - the matrix 10580 10581 Output Parameters: 10582 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10583 10584 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10585 10586 Level: advanced 10587 10588 .seealso: MatInvertBockDiagonal() 10589 @*/ 10590 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10591 { 10592 PetscErrorCode ierr; 10593 const PetscScalar *vals; 10594 PetscInt *dnnz; 10595 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10596 10597 PetscFunctionBegin; 10598 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10599 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10600 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10601 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10602 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10603 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10604 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10605 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10606 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10607 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10608 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10609 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10610 for (i = rstart/bs; i < rend/bs; i++) { 10611 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10612 } 10613 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10614 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10615 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10616 PetscFunctionReturn(0); 10617 } 10618 10619 /*@C 10620 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10621 via MatTransposeColoringCreate(). 10622 10623 Collective on MatTransposeColoring 10624 10625 Input Parameter: 10626 . c - coloring context 10627 10628 Level: intermediate 10629 10630 .seealso: MatTransposeColoringCreate() 10631 @*/ 10632 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10633 { 10634 PetscErrorCode ierr; 10635 MatTransposeColoring matcolor=*c; 10636 10637 PetscFunctionBegin; 10638 if (!matcolor) PetscFunctionReturn(0); 10639 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10640 10641 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10642 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10643 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10644 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10645 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10646 if (matcolor->brows>0) { 10647 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10648 } 10649 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10650 PetscFunctionReturn(0); 10651 } 10652 10653 /*@C 10654 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10655 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10656 MatTransposeColoring to sparse B. 10657 10658 Collective on MatTransposeColoring 10659 10660 Input Parameters: 10661 + B - sparse matrix B 10662 . Btdense - symbolic dense matrix B^T 10663 - coloring - coloring context created with MatTransposeColoringCreate() 10664 10665 Output Parameter: 10666 . Btdense - dense matrix B^T 10667 10668 Level: advanced 10669 10670 Notes: 10671 These are used internally for some implementations of MatRARt() 10672 10673 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10674 10675 .keywords: coloring 10676 @*/ 10677 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10678 { 10679 PetscErrorCode ierr; 10680 10681 PetscFunctionBegin; 10682 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10683 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10684 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10685 10686 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10687 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10688 PetscFunctionReturn(0); 10689 } 10690 10691 /*@C 10692 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10693 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10694 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10695 Csp from Cden. 10696 10697 Collective on MatTransposeColoring 10698 10699 Input Parameters: 10700 + coloring - coloring context created with MatTransposeColoringCreate() 10701 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10702 10703 Output Parameter: 10704 . Csp - sparse matrix 10705 10706 Level: advanced 10707 10708 Notes: 10709 These are used internally for some implementations of MatRARt() 10710 10711 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10712 10713 .keywords: coloring 10714 @*/ 10715 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10716 { 10717 PetscErrorCode ierr; 10718 10719 PetscFunctionBegin; 10720 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10721 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10722 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10723 10724 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10725 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10726 PetscFunctionReturn(0); 10727 } 10728 10729 /*@C 10730 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10731 10732 Collective on Mat 10733 10734 Input Parameters: 10735 + mat - the matrix product C 10736 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10737 10738 Output Parameter: 10739 . color - the new coloring context 10740 10741 Level: intermediate 10742 10743 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10744 MatTransColoringApplyDenToSp() 10745 @*/ 10746 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10747 { 10748 MatTransposeColoring c; 10749 MPI_Comm comm; 10750 PetscErrorCode ierr; 10751 10752 PetscFunctionBegin; 10753 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10754 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10755 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10756 10757 c->ctype = iscoloring->ctype; 10758 if (mat->ops->transposecoloringcreate) { 10759 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10760 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10761 10762 *color = c; 10763 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10764 PetscFunctionReturn(0); 10765 } 10766 10767 /*@ 10768 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10769 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10770 same, otherwise it will be larger 10771 10772 Not Collective 10773 10774 Input Parameter: 10775 . A - the matrix 10776 10777 Output Parameter: 10778 . state - the current state 10779 10780 Notes: 10781 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10782 different matrices 10783 10784 Level: intermediate 10785 10786 @*/ 10787 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10788 { 10789 PetscFunctionBegin; 10790 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10791 *state = mat->nonzerostate; 10792 PetscFunctionReturn(0); 10793 } 10794 10795 /*@ 10796 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10797 matrices from each processor 10798 10799 Collective on MPI_Comm 10800 10801 Input Parameters: 10802 + comm - the communicators the parallel matrix will live on 10803 . seqmat - the input sequential matrices 10804 . n - number of local columns (or PETSC_DECIDE) 10805 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10806 10807 Output Parameter: 10808 . mpimat - the parallel matrix generated 10809 10810 Level: advanced 10811 10812 Notes: 10813 The number of columns of the matrix in EACH processor MUST be the same. 10814 10815 @*/ 10816 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10817 { 10818 PetscErrorCode ierr; 10819 10820 PetscFunctionBegin; 10821 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10822 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"); 10823 10824 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10825 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10826 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10827 PetscFunctionReturn(0); 10828 } 10829 10830 /*@ 10831 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10832 ranks' ownership ranges. 10833 10834 Collective on A 10835 10836 Input Parameters: 10837 + A - the matrix to create subdomains from 10838 - N - requested number of subdomains 10839 10840 10841 Output Parameters: 10842 + n - number of subdomains resulting on this rank 10843 - iss - IS list with indices of subdomains on this rank 10844 10845 Level: advanced 10846 10847 Notes: 10848 number of subdomains must be smaller than the communicator size 10849 @*/ 10850 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10851 { 10852 MPI_Comm comm,subcomm; 10853 PetscMPIInt size,rank,color; 10854 PetscInt rstart,rend,k; 10855 PetscErrorCode ierr; 10856 10857 PetscFunctionBegin; 10858 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10859 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10860 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10861 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); 10862 *n = 1; 10863 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10864 color = rank/k; 10865 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10866 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10867 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10868 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10869 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10870 PetscFunctionReturn(0); 10871 } 10872 10873 /*@ 10874 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10875 10876 If the interpolation and restriction operators are the same, uses MatPtAP. 10877 If they are not the same, use MatMatMatMult. 10878 10879 Once the coarse grid problem is constructed, correct for interpolation operators 10880 that are not of full rank, which can legitimately happen in the case of non-nested 10881 geometric multigrid. 10882 10883 Input Parameters: 10884 + restrct - restriction operator 10885 . dA - fine grid matrix 10886 . interpolate - interpolation operator 10887 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10888 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10889 10890 Output Parameters: 10891 . A - the Galerkin coarse matrix 10892 10893 Options Database Key: 10894 . -pc_mg_galerkin <both,pmat,mat,none> 10895 10896 Level: developer 10897 10898 .keywords: MG, multigrid, Galerkin 10899 10900 .seealso: MatPtAP(), MatMatMatMult() 10901 @*/ 10902 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10903 { 10904 PetscErrorCode ierr; 10905 IS zerorows; 10906 Vec diag; 10907 10908 PetscFunctionBegin; 10909 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10910 /* Construct the coarse grid matrix */ 10911 if (interpolate == restrct) { 10912 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10913 } else { 10914 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10915 } 10916 10917 /* If the interpolation matrix is not of full rank, A will have zero rows. 10918 This can legitimately happen in the case of non-nested geometric multigrid. 10919 In that event, we set the rows of the matrix to the rows of the identity, 10920 ignoring the equations (as the RHS will also be zero). */ 10921 10922 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10923 10924 if (zerorows != NULL) { /* if there are any zero rows */ 10925 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10926 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10927 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10928 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10929 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10930 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10931 } 10932 PetscFunctionReturn(0); 10933 } 10934 10935 /*@C 10936 MatSetOperation - Allows user to set a matrix operation for any matrix type 10937 10938 Logically Collective on Mat 10939 10940 Input Parameters: 10941 + mat - the matrix 10942 . op - the name of the operation 10943 - f - the function that provides the operation 10944 10945 Level: developer 10946 10947 Usage: 10948 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10949 $ ierr = MatCreateXXX(comm,...&A); 10950 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10951 10952 Notes: 10953 See the file include/petscmat.h for a complete list of matrix 10954 operations, which all have the form MATOP_<OPERATION>, where 10955 <OPERATION> is the name (in all capital letters) of the 10956 user interface routine (e.g., MatMult() -> MATOP_MULT). 10957 10958 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10959 sequence as the usual matrix interface routines, since they 10960 are intended to be accessed via the usual matrix interface 10961 routines, e.g., 10962 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10963 10964 In particular each function MUST return an error code of 0 on success and 10965 nonzero on failure. 10966 10967 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10968 10969 .keywords: matrix, set, operation 10970 10971 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10972 @*/ 10973 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10974 { 10975 PetscFunctionBegin; 10976 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10977 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10978 mat->ops->viewnative = mat->ops->view; 10979 } 10980 (((void(**)(void))mat->ops)[op]) = f; 10981 PetscFunctionReturn(0); 10982 } 10983 10984 /*@C 10985 MatGetOperation - Gets a matrix operation for any matrix type. 10986 10987 Not Collective 10988 10989 Input Parameters: 10990 + mat - the matrix 10991 - op - the name of the operation 10992 10993 Output Parameter: 10994 . f - the function that provides the operation 10995 10996 Level: developer 10997 10998 Usage: 10999 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 11000 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 11001 11002 Notes: 11003 See the file include/petscmat.h for a complete list of matrix 11004 operations, which all have the form MATOP_<OPERATION>, where 11005 <OPERATION> is the name (in all capital letters) of the 11006 user interface routine (e.g., MatMult() -> MATOP_MULT). 11007 11008 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 11009 11010 .keywords: matrix, get, operation 11011 11012 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 11013 @*/ 11014 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 11015 { 11016 PetscFunctionBegin; 11017 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11018 *f = (((void (**)(void))mat->ops)[op]); 11019 PetscFunctionReturn(0); 11020 } 11021 11022 /*@ 11023 MatHasOperation - Determines whether the given matrix supports the particular 11024 operation. 11025 11026 Not Collective 11027 11028 Input Parameters: 11029 + mat - the matrix 11030 - op - the operation, for example, MATOP_GET_DIAGONAL 11031 11032 Output Parameter: 11033 . has - either PETSC_TRUE or PETSC_FALSE 11034 11035 Level: advanced 11036 11037 Notes: 11038 See the file include/petscmat.h for a complete list of matrix 11039 operations, which all have the form MATOP_<OPERATION>, where 11040 <OPERATION> is the name (in all capital letters) of the 11041 user-level routine. E.g., MatNorm() -> MATOP_NORM. 11042 11043 .keywords: matrix, has, operation 11044 11045 .seealso: MatCreateShell() 11046 @*/ 11047 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 11048 { 11049 PetscErrorCode ierr; 11050 11051 PetscFunctionBegin; 11052 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11053 PetscValidType(mat,1); 11054 PetscValidPointer(has,3); 11055 if (mat->ops->hasoperation) { 11056 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 11057 } else { 11058 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 11059 else { 11060 *has = PETSC_FALSE; 11061 if (op == MATOP_CREATE_SUBMATRIX) { 11062 PetscMPIInt size; 11063 11064 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 11065 if (size == 1) { 11066 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 11067 } 11068 } 11069 } 11070 } 11071 PetscFunctionReturn(0); 11072 } 11073 11074 /*@ 11075 MatHasCongruentLayouts - Determines whether the rows and columns layouts 11076 of the matrix are congruent 11077 11078 Collective on mat 11079 11080 Input Parameters: 11081 . mat - the matrix 11082 11083 Output Parameter: 11084 . cong - either PETSC_TRUE or PETSC_FALSE 11085 11086 Level: beginner 11087 11088 Notes: 11089 11090 .keywords: matrix, has 11091 11092 .seealso: MatCreate(), MatSetSizes() 11093 @*/ 11094 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11095 { 11096 PetscErrorCode ierr; 11097 11098 PetscFunctionBegin; 11099 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11100 PetscValidType(mat,1); 11101 PetscValidPointer(cong,2); 11102 if (!mat->rmap || !mat->cmap) { 11103 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11104 PetscFunctionReturn(0); 11105 } 11106 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11107 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 11108 if (*cong) mat->congruentlayouts = 1; 11109 else mat->congruentlayouts = 0; 11110 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11111 PetscFunctionReturn(0); 11112 } 11113 11114 /*@ 11115 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 11116 e.g., matrx product of MatPtAP. 11117 11118 Collective on mat 11119 11120 Input Parameters: 11121 . mat - the matrix 11122 11123 Output Parameter: 11124 . mat - the matrix with intermediate data structures released 11125 11126 Level: advanced 11127 11128 Notes: 11129 11130 .keywords: matrix 11131 11132 .seealso: MatPtAP(), MatMatMult() 11133 @*/ 11134 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 11135 { 11136 PetscErrorCode ierr; 11137 11138 PetscFunctionBegin; 11139 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11140 PetscValidType(mat,1); 11141 if (mat->ops->freeintermediatedatastructures) { 11142 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 11143 } 11144 PetscFunctionReturn(0); 11145 } 11146