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