1 2 /* 3 This is where the abstract matrix operations are defined 4 */ 5 6 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 7 #include <petsc/private/isimpl.h> 8 #include <petsc/private/vecimpl.h> 9 10 /* Logging support */ 11 PetscClassId MAT_CLASSID; 12 PetscClassId MAT_COLORING_CLASSID; 13 PetscClassId MAT_FDCOLORING_CLASSID; 14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 15 16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 36 PetscLogEvent MAT_ViennaCLCopyToGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 39 40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 41 42 /*@ 43 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations 44 45 Logically Collective on Mat 46 47 Input Parameters: 48 + x - the matrix 49 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 50 it will create one internally. 51 52 Output Parameter: 53 . x - the matrix 54 55 Example of Usage: 56 .vb 57 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 58 MatSetRandom(x,rctx); 59 PetscRandomDestroy(rctx); 60 .ve 61 62 Level: intermediate 63 64 Concepts: matrix^setting to random 65 Concepts: random^matrix 66 67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 68 @*/ 69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 70 { 71 PetscErrorCode ierr; 72 PetscRandom randObj = NULL; 73 74 PetscFunctionBegin; 75 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 76 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 77 PetscValidType(x,1); 78 79 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 80 81 if (!rctx) { 82 MPI_Comm comm; 83 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 84 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 85 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 86 rctx = randObj; 87 } 88 89 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 91 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 92 93 x->assembled = PETSC_TRUE; 94 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 95 PetscFunctionReturn(0); 96 } 97 98 /*@ 99 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 100 101 Logically Collective on Mat 102 103 Input Parameters: 104 . mat - the factored matrix 105 106 Output Parameter: 107 + pivot - the pivot value computed 108 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 109 the share the matrix 110 111 Level: advanced 112 113 Notes: 114 This routine does not work for factorizations done with external packages. 115 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 116 117 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 118 119 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 120 @*/ 121 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 122 { 123 PetscFunctionBegin; 124 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 125 *pivot = mat->factorerror_zeropivot_value; 126 *row = mat->factorerror_zeropivot_row; 127 PetscFunctionReturn(0); 128 } 129 130 /*@ 131 MatFactorGetError - gets the error code from a factorization 132 133 Logically Collective on Mat 134 135 Input Parameters: 136 . mat - the factored matrix 137 138 Output Parameter: 139 . err - the error code 140 141 Level: advanced 142 143 Notes: 144 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 145 146 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 147 @*/ 148 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 149 { 150 PetscFunctionBegin; 151 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 152 *err = mat->factorerrortype; 153 PetscFunctionReturn(0); 154 } 155 156 /*@ 157 MatFactorClearError - clears the error code in a factorization 158 159 Logically Collective on Mat 160 161 Input Parameter: 162 . mat - the factored matrix 163 164 Level: developer 165 166 Notes: 167 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 168 169 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 170 @*/ 171 PetscErrorCode MatFactorClearError(Mat mat) 172 { 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 175 mat->factorerrortype = MAT_FACTOR_NOERROR; 176 mat->factorerror_zeropivot_value = 0.0; 177 mat->factorerror_zeropivot_row = 0; 178 PetscFunctionReturn(0); 179 } 180 181 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 182 { 183 PetscErrorCode ierr; 184 Vec r,l; 185 const PetscScalar *al; 186 PetscInt i,nz,gnz,N,n; 187 188 PetscFunctionBegin; 189 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 190 if (!cols) { /* nonzero rows */ 191 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 192 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 193 ierr = VecSet(l,0.0);CHKERRQ(ierr); 194 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 195 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 196 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 197 } else { /* nonzero columns */ 198 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 199 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 200 ierr = VecSet(r,0.0);CHKERRQ(ierr); 201 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 202 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 203 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 204 } 205 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 206 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 207 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 208 if (gnz != N) { 209 PetscInt *nzr; 210 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 211 if (nz) { 212 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 213 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 214 } 215 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 216 } else *nonzero = NULL; 217 if (!cols) { /* nonzero rows */ 218 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 219 } else { 220 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 221 } 222 ierr = VecDestroy(&l);CHKERRQ(ierr); 223 ierr = VecDestroy(&r);CHKERRQ(ierr); 224 PetscFunctionReturn(0); 225 } 226 227 /*@ 228 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 229 230 Input Parameter: 231 . A - the matrix 232 233 Output Parameter: 234 . keptrows - the rows that are not completely zero 235 236 Notes: 237 keptrows is set to NULL if all rows are nonzero. 238 239 Level: intermediate 240 241 @*/ 242 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 243 { 244 PetscErrorCode ierr; 245 246 PetscFunctionBegin; 247 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 248 PetscValidType(mat,1); 249 PetscValidPointer(keptrows,2); 250 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 251 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 252 if (!mat->ops->findnonzerorows) { 253 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 254 } else { 255 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 256 } 257 PetscFunctionReturn(0); 258 } 259 260 /*@ 261 MatFindZeroRows - Locate all rows that are completely zero in the matrix 262 263 Input Parameter: 264 . A - the matrix 265 266 Output Parameter: 267 . zerorows - the rows that are completely zero 268 269 Notes: 270 zerorows is set to NULL if no rows are zero. 271 272 Level: intermediate 273 274 @*/ 275 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 276 { 277 PetscErrorCode ierr; 278 IS keptrows; 279 PetscInt m, n; 280 281 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 282 PetscValidType(mat,1); 283 284 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 285 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 286 In keeping with this convention, we set zerorows to NULL if there are no zero 287 rows. */ 288 if (keptrows == NULL) { 289 *zerorows = NULL; 290 } else { 291 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 292 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 293 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 294 } 295 PetscFunctionReturn(0); 296 } 297 298 /*@ 299 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 300 301 Not Collective 302 303 Input Parameters: 304 . A - the matrix 305 306 Output Parameters: 307 . a - the diagonal part (which is a SEQUENTIAL matrix) 308 309 Notes: 310 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 311 Use caution, as the reference count on the returned matrix is not incremented and it is used as 312 part of the containing MPI Mat's normal operation. 313 314 Level: advanced 315 316 @*/ 317 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 318 { 319 PetscErrorCode ierr; 320 321 PetscFunctionBegin; 322 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 323 PetscValidType(A,1); 324 PetscValidPointer(a,3); 325 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 326 if (!A->ops->getdiagonalblock) { 327 PetscMPIInt size; 328 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 329 if (size == 1) { 330 *a = A; 331 PetscFunctionReturn(0); 332 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 333 } 334 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 335 PetscFunctionReturn(0); 336 } 337 338 /*@ 339 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 340 341 Collective on Mat 342 343 Input Parameters: 344 . mat - the matrix 345 346 Output Parameter: 347 . trace - the sum of the diagonal entries 348 349 Level: advanced 350 351 @*/ 352 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 353 { 354 PetscErrorCode ierr; 355 Vec diag; 356 357 PetscFunctionBegin; 358 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 359 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 360 ierr = VecSum(diag,trace);CHKERRQ(ierr); 361 ierr = VecDestroy(&diag);CHKERRQ(ierr); 362 PetscFunctionReturn(0); 363 } 364 365 /*@ 366 MatRealPart - Zeros out the imaginary part of the matrix 367 368 Logically Collective on Mat 369 370 Input Parameters: 371 . mat - the matrix 372 373 Level: advanced 374 375 376 .seealso: MatImaginaryPart() 377 @*/ 378 PetscErrorCode MatRealPart(Mat mat) 379 { 380 PetscErrorCode ierr; 381 382 PetscFunctionBegin; 383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 384 PetscValidType(mat,1); 385 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 386 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 387 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 388 MatCheckPreallocated(mat,1); 389 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 390 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 391 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 392 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 393 } 394 #endif 395 PetscFunctionReturn(0); 396 } 397 398 /*@C 399 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 400 401 Collective on Mat 402 403 Input Parameter: 404 . mat - the matrix 405 406 Output Parameters: 407 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 408 - ghosts - the global indices of the ghost points 409 410 Notes: 411 the nghosts and ghosts are suitable to pass into VecCreateGhost() 412 413 Level: advanced 414 415 @*/ 416 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 417 { 418 PetscErrorCode ierr; 419 420 PetscFunctionBegin; 421 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 422 PetscValidType(mat,1); 423 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 424 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 425 if (!mat->ops->getghosts) { 426 if (nghosts) *nghosts = 0; 427 if (ghosts) *ghosts = 0; 428 } else { 429 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 430 } 431 PetscFunctionReturn(0); 432 } 433 434 435 /*@ 436 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 437 438 Logically Collective on Mat 439 440 Input Parameters: 441 . mat - the matrix 442 443 Level: advanced 444 445 446 .seealso: MatRealPart() 447 @*/ 448 PetscErrorCode MatImaginaryPart(Mat mat) 449 { 450 PetscErrorCode ierr; 451 452 PetscFunctionBegin; 453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 454 PetscValidType(mat,1); 455 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 456 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 457 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 458 MatCheckPreallocated(mat,1); 459 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 460 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 461 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 462 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 463 } 464 #endif 465 PetscFunctionReturn(0); 466 } 467 468 /*@ 469 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 470 471 Not Collective 472 473 Input Parameter: 474 . mat - the matrix 475 476 Output Parameters: 477 + missing - is any diagonal missing 478 - dd - first diagonal entry that is missing (optional) on this process 479 480 Level: advanced 481 482 483 .seealso: MatRealPart() 484 @*/ 485 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 486 { 487 PetscErrorCode ierr; 488 489 PetscFunctionBegin; 490 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 491 PetscValidType(mat,1); 492 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 493 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 494 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 495 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 496 PetscFunctionReturn(0); 497 } 498 499 /*@C 500 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 501 for each row that you get to ensure that your application does 502 not bleed memory. 503 504 Not Collective 505 506 Input Parameters: 507 + mat - the matrix 508 - row - the row to get 509 510 Output Parameters: 511 + ncols - if not NULL, the number of nonzeros in the row 512 . cols - if not NULL, the column numbers 513 - vals - if not NULL, the values 514 515 Notes: 516 This routine is provided for people who need to have direct access 517 to the structure of a matrix. We hope that we provide enough 518 high-level matrix routines that few users will need it. 519 520 MatGetRow() always returns 0-based column indices, regardless of 521 whether the internal representation is 0-based (default) or 1-based. 522 523 For better efficiency, set cols and/or vals to NULL if you do 524 not wish to extract these quantities. 525 526 The user can only examine the values extracted with MatGetRow(); 527 the values cannot be altered. To change the matrix entries, one 528 must use MatSetValues(). 529 530 You can only have one call to MatGetRow() outstanding for a particular 531 matrix at a time, per processor. MatGetRow() can only obtain rows 532 associated with the given processor, it cannot get rows from the 533 other processors; for that we suggest using MatCreateSubMatrices(), then 534 MatGetRow() on the submatrix. The row index passed to MatGetRow() 535 is in the global number of rows. 536 537 Fortran Notes: 538 The calling sequence from Fortran is 539 .vb 540 MatGetRow(matrix,row,ncols,cols,values,ierr) 541 Mat matrix (input) 542 integer row (input) 543 integer ncols (output) 544 integer cols(maxcols) (output) 545 double precision (or double complex) values(maxcols) output 546 .ve 547 where maxcols >= maximum nonzeros in any row of the matrix. 548 549 550 Caution: 551 Do not try to change the contents of the output arrays (cols and vals). 552 In some cases, this may corrupt the matrix. 553 554 Level: advanced 555 556 Concepts: matrices^row access 557 558 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 559 @*/ 560 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 561 { 562 PetscErrorCode ierr; 563 PetscInt incols; 564 565 PetscFunctionBegin; 566 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 567 PetscValidType(mat,1); 568 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 569 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 570 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 571 MatCheckPreallocated(mat,1); 572 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 573 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 574 if (ncols) *ncols = incols; 575 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 576 PetscFunctionReturn(0); 577 } 578 579 /*@ 580 MatConjugate - replaces the matrix values with their complex conjugates 581 582 Logically Collective on Mat 583 584 Input Parameters: 585 . mat - the matrix 586 587 Level: advanced 588 589 .seealso: VecConjugate() 590 @*/ 591 PetscErrorCode MatConjugate(Mat mat) 592 { 593 #if defined(PETSC_USE_COMPLEX) 594 PetscErrorCode ierr; 595 596 PetscFunctionBegin; 597 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 598 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 599 if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov"); 600 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 601 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 602 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 603 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 604 } 605 #endif 606 PetscFunctionReturn(0); 607 #else 608 return 0; 609 #endif 610 } 611 612 /*@C 613 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 614 615 Not Collective 616 617 Input Parameters: 618 + mat - the matrix 619 . row - the row to get 620 . ncols, cols - the number of nonzeros and their columns 621 - vals - if nonzero the column values 622 623 Notes: 624 This routine should be called after you have finished examining the entries. 625 626 This routine zeros out ncols, cols, and vals. This is to prevent accidental 627 us of the array after it has been restored. If you pass NULL, it will 628 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 629 630 Fortran Notes: 631 The calling sequence from Fortran is 632 .vb 633 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 634 Mat matrix (input) 635 integer row (input) 636 integer ncols (output) 637 integer cols(maxcols) (output) 638 double precision (or double complex) values(maxcols) output 639 .ve 640 Where maxcols >= maximum nonzeros in any row of the matrix. 641 642 In Fortran MatRestoreRow() MUST be called after MatGetRow() 643 before another call to MatGetRow() can be made. 644 645 Level: advanced 646 647 .seealso: MatGetRow() 648 @*/ 649 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 650 { 651 PetscErrorCode ierr; 652 653 PetscFunctionBegin; 654 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 655 if (ncols) PetscValidIntPointer(ncols,3); 656 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 657 if (!mat->ops->restorerow) PetscFunctionReturn(0); 658 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 659 if (ncols) *ncols = 0; 660 if (cols) *cols = NULL; 661 if (vals) *vals = NULL; 662 PetscFunctionReturn(0); 663 } 664 665 /*@ 666 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 667 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 668 669 Not Collective 670 671 Input Parameters: 672 + mat - the matrix 673 674 Notes: 675 The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format. 676 677 Level: advanced 678 679 Concepts: matrices^row access 680 681 .seealso: MatRestoreRowRowUpperTriangular() 682 @*/ 683 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 684 { 685 PetscErrorCode ierr; 686 687 PetscFunctionBegin; 688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 689 PetscValidType(mat,1); 690 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 691 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 692 if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 693 MatCheckPreallocated(mat,1); 694 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 695 PetscFunctionReturn(0); 696 } 697 698 /*@ 699 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 700 701 Not Collective 702 703 Input Parameters: 704 + mat - the matrix 705 706 Notes: 707 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 708 709 710 Level: advanced 711 712 .seealso: MatGetRowUpperTriangular() 713 @*/ 714 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 715 { 716 PetscErrorCode ierr; 717 718 PetscFunctionBegin; 719 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 720 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 721 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 722 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 723 PetscFunctionReturn(0); 724 } 725 726 /*@C 727 MatSetOptionsPrefix - Sets the prefix used for searching for all 728 Mat options in the database. 729 730 Logically Collective on Mat 731 732 Input Parameter: 733 + A - the Mat context 734 - prefix - the prefix to prepend to all option names 735 736 Notes: 737 A hyphen (-) must NOT be given at the beginning of the prefix name. 738 The first character of all runtime options is AUTOMATICALLY the hyphen. 739 740 Level: advanced 741 742 .keywords: Mat, set, options, prefix, database 743 744 .seealso: MatSetFromOptions() 745 @*/ 746 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 747 { 748 PetscErrorCode ierr; 749 750 PetscFunctionBegin; 751 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 752 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 753 PetscFunctionReturn(0); 754 } 755 756 /*@C 757 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 758 Mat options in the database. 759 760 Logically Collective on Mat 761 762 Input Parameters: 763 + A - the Mat context 764 - prefix - the prefix to prepend to all option names 765 766 Notes: 767 A hyphen (-) must NOT be given at the beginning of the prefix name. 768 The first character of all runtime options is AUTOMATICALLY the hyphen. 769 770 Level: advanced 771 772 .keywords: Mat, append, options, prefix, database 773 774 .seealso: MatGetOptionsPrefix() 775 @*/ 776 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 777 { 778 PetscErrorCode ierr; 779 780 PetscFunctionBegin; 781 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 782 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 783 PetscFunctionReturn(0); 784 } 785 786 /*@C 787 MatGetOptionsPrefix - Sets the prefix used for searching for all 788 Mat options in the database. 789 790 Not Collective 791 792 Input Parameter: 793 . A - the Mat context 794 795 Output Parameter: 796 . prefix - pointer to the prefix string used 797 798 Notes: 799 On the fortran side, the user should pass in a string 'prefix' of 800 sufficient length to hold the prefix. 801 802 Level: advanced 803 804 .keywords: Mat, get, options, prefix, database 805 806 .seealso: MatAppendOptionsPrefix() 807 @*/ 808 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 809 { 810 PetscErrorCode ierr; 811 812 PetscFunctionBegin; 813 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 814 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 815 PetscFunctionReturn(0); 816 } 817 818 /*@ 819 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 820 821 Collective on Mat 822 823 Input Parameters: 824 . A - the Mat context 825 826 Notes: 827 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 828 Currently support MPIAIJ and SEQAIJ. 829 830 Level: beginner 831 832 .keywords: Mat, ResetPreallocation 833 834 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 835 @*/ 836 PetscErrorCode MatResetPreallocation(Mat A) 837 { 838 PetscErrorCode ierr; 839 840 PetscFunctionBegin; 841 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 842 PetscValidType(A,1); 843 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 844 PetscFunctionReturn(0); 845 } 846 847 848 /*@ 849 MatSetUp - Sets up the internal matrix data structures for the later use. 850 851 Collective on Mat 852 853 Input Parameters: 854 . A - the Mat context 855 856 Notes: 857 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 858 859 If a suitable preallocation routine is used, this function does not need to be called. 860 861 See the Performance chapter of the PETSc users manual for how to preallocate matrices 862 863 Level: beginner 864 865 .keywords: Mat, setup 866 867 .seealso: MatCreate(), MatDestroy() 868 @*/ 869 PetscErrorCode MatSetUp(Mat A) 870 { 871 PetscMPIInt size; 872 PetscErrorCode ierr; 873 874 PetscFunctionBegin; 875 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 876 if (!((PetscObject)A)->type_name) { 877 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 878 if (size == 1) { 879 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 880 } else { 881 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 882 } 883 } 884 if (!A->preallocated && A->ops->setup) { 885 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 886 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 887 } 888 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 889 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 890 A->preallocated = PETSC_TRUE; 891 PetscFunctionReturn(0); 892 } 893 894 #if defined(PETSC_HAVE_SAWS) 895 #include <petscviewersaws.h> 896 #endif 897 /*@C 898 MatView - Visualizes a matrix object. 899 900 Collective on Mat 901 902 Input Parameters: 903 + mat - the matrix 904 - viewer - visualization context 905 906 Notes: 907 The available visualization contexts include 908 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 909 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 910 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 911 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 912 913 The user can open alternative visualization contexts with 914 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 915 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 916 specified file; corresponding input uses MatLoad() 917 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 918 an X window display 919 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 920 Currently only the sequential dense and AIJ 921 matrix types support the Socket viewer. 922 923 The user can call PetscViewerPushFormat() to specify the output 924 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 925 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 926 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 927 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 928 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 929 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 930 format common among all matrix types 931 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 932 format (which is in many cases the same as the default) 933 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 934 size and structure (not the matrix entries) 935 . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 936 the matrix structure 937 938 Options Database Keys: 939 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 940 . -mat_view ::ascii_info_detail - Prints more detailed info 941 . -mat_view - Prints matrix in ASCII format 942 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 943 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 944 . -display <name> - Sets display name (default is host) 945 . -draw_pause <sec> - Sets number of seconds to pause after display 946 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 947 . -viewer_socket_machine <machine> - 948 . -viewer_socket_port <port> - 949 . -mat_view binary - save matrix to file in binary format 950 - -viewer_binary_filename <name> - 951 Level: beginner 952 953 Notes: 954 see the manual page for MatLoad() for the exact format of the binary file when the binary 955 viewer is used. 956 957 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 958 viewer is used. 959 960 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure. 961 And then use the following mouse functions: 962 left mouse: zoom in 963 middle mouse: zoom out 964 right mouse: continue with the simulation 965 966 Concepts: matrices^viewing 967 Concepts: matrices^plotting 968 Concepts: matrices^printing 969 970 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 971 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 972 @*/ 973 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 974 { 975 PetscErrorCode ierr; 976 PetscInt rows,cols,rbs,cbs; 977 PetscBool iascii,ibinary; 978 PetscViewerFormat format; 979 PetscMPIInt size; 980 #if defined(PETSC_HAVE_SAWS) 981 PetscBool issaws; 982 #endif 983 984 PetscFunctionBegin; 985 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 986 PetscValidType(mat,1); 987 if (!viewer) { 988 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 989 } 990 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 991 PetscCheckSameComm(mat,1,viewer,2); 992 MatCheckPreallocated(mat,1); 993 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 994 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 995 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 996 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 997 if (ibinary) { 998 PetscBool mpiio; 999 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 1000 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 1001 } 1002 1003 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1004 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1005 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1006 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 1007 } 1008 1009 #if defined(PETSC_HAVE_SAWS) 1010 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1011 #endif 1012 if (iascii) { 1013 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1014 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1015 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1016 MatNullSpace nullsp,transnullsp; 1017 1018 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1019 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1020 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1021 if (rbs != 1 || cbs != 1) { 1022 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1023 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1024 } else { 1025 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1026 } 1027 if (mat->factortype) { 1028 MatSolverType solver; 1029 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1030 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1031 } 1032 if (mat->ops->getinfo) { 1033 MatInfo info; 1034 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1035 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1036 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1037 } 1038 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1039 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1040 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1041 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1042 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1043 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1044 } 1045 #if defined(PETSC_HAVE_SAWS) 1046 } else if (issaws) { 1047 PetscMPIInt rank; 1048 1049 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1050 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1051 if (!((PetscObject)mat)->amsmem && !rank) { 1052 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1053 } 1054 #endif 1055 } 1056 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1057 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1058 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1059 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1060 } else if (mat->ops->view) { 1061 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1062 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1063 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1064 } 1065 if (iascii) { 1066 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1067 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1068 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1069 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1070 } 1071 } 1072 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1073 PetscFunctionReturn(0); 1074 } 1075 1076 #if defined(PETSC_USE_DEBUG) 1077 #include <../src/sys/totalview/tv_data_display.h> 1078 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1079 { 1080 TV_add_row("Local rows", "int", &mat->rmap->n); 1081 TV_add_row("Local columns", "int", &mat->cmap->n); 1082 TV_add_row("Global rows", "int", &mat->rmap->N); 1083 TV_add_row("Global columns", "int", &mat->cmap->N); 1084 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1085 return TV_format_OK; 1086 } 1087 #endif 1088 1089 /*@C 1090 MatLoad - Loads a matrix that has been stored in binary format 1091 with MatView(). The matrix format is determined from the options database. 1092 Generates a parallel MPI matrix if the communicator has more than one 1093 processor. The default matrix type is AIJ. 1094 1095 Collective on PetscViewer 1096 1097 Input Parameters: 1098 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1099 or some related function before a call to MatLoad() 1100 - viewer - binary file viewer, created with PetscViewerBinaryOpen() 1101 1102 Options Database Keys: 1103 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1104 block size 1105 . -matload_block_size <bs> 1106 1107 Level: beginner 1108 1109 Notes: 1110 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1111 Mat before calling this routine if you wish to set it from the options database. 1112 1113 MatLoad() automatically loads into the options database any options 1114 given in the file filename.info where filename is the name of the file 1115 that was passed to the PetscViewerBinaryOpen(). The options in the info 1116 file will be ignored if you use the -viewer_binary_skip_info option. 1117 1118 If the type or size of newmat is not set before a call to MatLoad, PETSc 1119 sets the default matrix type AIJ and sets the local and global sizes. 1120 If type and/or size is already set, then the same are used. 1121 1122 In parallel, each processor can load a subset of rows (or the 1123 entire matrix). This routine is especially useful when a large 1124 matrix is stored on disk and only part of it is desired on each 1125 processor. For example, a parallel solver may access only some of 1126 the rows from each processor. The algorithm used here reads 1127 relatively small blocks of data rather than reading the entire 1128 matrix and then subsetting it. 1129 1130 Notes for advanced users: 1131 Most users should not need to know the details of the binary storage 1132 format, since MatLoad() and MatView() completely hide these details. 1133 But for anyone who's interested, the standard binary matrix storage 1134 format is 1135 1136 $ int MAT_FILE_CLASSID 1137 $ int number of rows 1138 $ int number of columns 1139 $ int total number of nonzeros 1140 $ int *number nonzeros in each row 1141 $ int *column indices of all nonzeros (starting index is zero) 1142 $ PetscScalar *values of all nonzeros 1143 1144 PETSc automatically does the byte swapping for 1145 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1146 linux, Windows and the paragon; thus if you write your own binary 1147 read/write routines you have to swap the bytes; see PetscBinaryRead() 1148 and PetscBinaryWrite() to see how this may be done. 1149 1150 .keywords: matrix, load, binary, input 1151 1152 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad() 1153 1154 @*/ 1155 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1156 { 1157 PetscErrorCode ierr; 1158 PetscBool isbinary,flg; 1159 1160 PetscFunctionBegin; 1161 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1162 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1163 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1164 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1165 1166 if (!((PetscObject)newmat)->type_name) { 1167 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1168 } 1169 1170 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1171 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1172 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1173 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1174 1175 flg = PETSC_FALSE; 1176 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1177 if (flg) { 1178 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1179 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1180 } 1181 flg = PETSC_FALSE; 1182 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1183 if (flg) { 1184 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1185 } 1186 PetscFunctionReturn(0); 1187 } 1188 1189 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1190 { 1191 PetscErrorCode ierr; 1192 Mat_Redundant *redund = *redundant; 1193 PetscInt i; 1194 1195 PetscFunctionBegin; 1196 if (redund){ 1197 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1198 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1199 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1200 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1201 } else { 1202 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1203 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1204 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1205 for (i=0; i<redund->nrecvs; i++) { 1206 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1207 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1208 } 1209 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1210 } 1211 1212 if (redund->subcomm) { 1213 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1214 } 1215 ierr = PetscFree(redund);CHKERRQ(ierr); 1216 } 1217 PetscFunctionReturn(0); 1218 } 1219 1220 /*@ 1221 MatDestroy - Frees space taken by a matrix. 1222 1223 Collective on Mat 1224 1225 Input Parameter: 1226 . A - the matrix 1227 1228 Level: beginner 1229 1230 @*/ 1231 PetscErrorCode MatDestroy(Mat *A) 1232 { 1233 PetscErrorCode ierr; 1234 1235 PetscFunctionBegin; 1236 if (!*A) PetscFunctionReturn(0); 1237 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1238 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1239 1240 /* if memory was published with SAWs then destroy it */ 1241 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1242 if ((*A)->ops->destroy) { 1243 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1244 } 1245 1246 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1247 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1248 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1249 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1250 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1251 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1252 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1253 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1254 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1255 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1256 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1257 PetscFunctionReturn(0); 1258 } 1259 1260 /*@C 1261 MatSetValues - Inserts or adds a block of values into a matrix. 1262 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1263 MUST be called after all calls to MatSetValues() have been completed. 1264 1265 Not Collective 1266 1267 Input Parameters: 1268 + mat - the matrix 1269 . v - a logically two-dimensional array of values 1270 . m, idxm - the number of rows and their global indices 1271 . n, idxn - the number of columns and their global indices 1272 - addv - either ADD_VALUES or INSERT_VALUES, where 1273 ADD_VALUES adds values to any existing entries, and 1274 INSERT_VALUES replaces existing entries with new values 1275 1276 Notes: 1277 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1278 MatSetUp() before using this routine 1279 1280 By default the values, v, are row-oriented. See MatSetOption() for other options. 1281 1282 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1283 options cannot be mixed without intervening calls to the assembly 1284 routines. 1285 1286 MatSetValues() uses 0-based row and column numbers in Fortran 1287 as well as in C. 1288 1289 Negative indices may be passed in idxm and idxn, these rows and columns are 1290 simply ignored. This allows easily inserting element stiffness matrices 1291 with homogeneous Dirchlet boundary conditions that you don't want represented 1292 in the matrix. 1293 1294 Efficiency Alert: 1295 The routine MatSetValuesBlocked() may offer much better efficiency 1296 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1297 1298 Level: beginner 1299 1300 Developer Notes: 1301 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1302 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1303 1304 Concepts: matrices^putting entries in 1305 1306 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1307 InsertMode, INSERT_VALUES, ADD_VALUES 1308 @*/ 1309 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1310 { 1311 PetscErrorCode ierr; 1312 #if defined(PETSC_USE_DEBUG) 1313 PetscInt i,j; 1314 #endif 1315 1316 PetscFunctionBeginHot; 1317 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1318 PetscValidType(mat,1); 1319 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1320 PetscValidIntPointer(idxm,3); 1321 PetscValidIntPointer(idxn,5); 1322 PetscValidScalarPointer(v,6); 1323 MatCheckPreallocated(mat,1); 1324 if (mat->insertmode == NOT_SET_VALUES) { 1325 mat->insertmode = addv; 1326 } 1327 #if defined(PETSC_USE_DEBUG) 1328 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1329 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1330 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1331 1332 for (i=0; i<m; i++) { 1333 for (j=0; j<n; j++) { 1334 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1335 #if defined(PETSC_USE_COMPLEX) 1336 SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1337 #else 1338 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1339 #endif 1340 } 1341 } 1342 #endif 1343 1344 if (mat->assembled) { 1345 mat->was_assembled = PETSC_TRUE; 1346 mat->assembled = PETSC_FALSE; 1347 } 1348 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1349 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1350 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1351 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1352 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1353 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1354 } 1355 #endif 1356 PetscFunctionReturn(0); 1357 } 1358 1359 1360 /*@ 1361 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1362 values into a matrix 1363 1364 Not Collective 1365 1366 Input Parameters: 1367 + mat - the matrix 1368 . row - the (block) row to set 1369 - v - a logically two-dimensional array of values 1370 1371 Notes: 1372 By the values, v, are column-oriented (for the block version) and sorted 1373 1374 All the nonzeros in the row must be provided 1375 1376 The matrix must have previously had its column indices set 1377 1378 The row must belong to this process 1379 1380 Level: intermediate 1381 1382 Concepts: matrices^putting entries in 1383 1384 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1385 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1386 @*/ 1387 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1388 { 1389 PetscErrorCode ierr; 1390 PetscInt globalrow; 1391 1392 PetscFunctionBegin; 1393 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1394 PetscValidType(mat,1); 1395 PetscValidScalarPointer(v,2); 1396 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1397 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1398 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1399 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1400 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1401 } 1402 #endif 1403 PetscFunctionReturn(0); 1404 } 1405 1406 /*@ 1407 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1408 values into a matrix 1409 1410 Not Collective 1411 1412 Input Parameters: 1413 + mat - the matrix 1414 . row - the (block) row to set 1415 - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values 1416 1417 Notes: 1418 The values, v, are column-oriented for the block version. 1419 1420 All the nonzeros in the row must be provided 1421 1422 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1423 1424 The row must belong to this process 1425 1426 Level: advanced 1427 1428 Concepts: matrices^putting entries in 1429 1430 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1431 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1432 @*/ 1433 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1434 { 1435 PetscErrorCode ierr; 1436 1437 PetscFunctionBeginHot; 1438 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1439 PetscValidType(mat,1); 1440 MatCheckPreallocated(mat,1); 1441 PetscValidScalarPointer(v,2); 1442 #if defined(PETSC_USE_DEBUG) 1443 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1444 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1445 #endif 1446 mat->insertmode = INSERT_VALUES; 1447 1448 if (mat->assembled) { 1449 mat->was_assembled = PETSC_TRUE; 1450 mat->assembled = PETSC_FALSE; 1451 } 1452 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1453 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1454 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1455 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1456 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1457 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1458 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1459 } 1460 #endif 1461 PetscFunctionReturn(0); 1462 } 1463 1464 /*@ 1465 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1466 Using structured grid indexing 1467 1468 Not Collective 1469 1470 Input Parameters: 1471 + mat - the matrix 1472 . m - number of rows being entered 1473 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1474 . n - number of columns being entered 1475 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1476 . v - a logically two-dimensional array of values 1477 - addv - either ADD_VALUES or INSERT_VALUES, where 1478 ADD_VALUES adds values to any existing entries, and 1479 INSERT_VALUES replaces existing entries with new values 1480 1481 Notes: 1482 By default the values, v, are row-oriented. See MatSetOption() for other options. 1483 1484 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1485 options cannot be mixed without intervening calls to the assembly 1486 routines. 1487 1488 The grid coordinates are across the entire grid, not just the local portion 1489 1490 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1491 as well as in C. 1492 1493 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1494 1495 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1496 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1497 1498 The columns and rows in the stencil passed in MUST be contained within the 1499 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1500 if you create a DMDA with an overlap of one grid level and on a particular process its first 1501 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1502 first i index you can use in your column and row indices in MatSetStencil() is 5. 1503 1504 In Fortran idxm and idxn should be declared as 1505 $ MatStencil idxm(4,m),idxn(4,n) 1506 and the values inserted using 1507 $ idxm(MatStencil_i,1) = i 1508 $ idxm(MatStencil_j,1) = j 1509 $ idxm(MatStencil_k,1) = k 1510 $ idxm(MatStencil_c,1) = c 1511 etc 1512 1513 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1514 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1515 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1516 DM_BOUNDARY_PERIODIC boundary type. 1517 1518 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 1519 a single value per point) you can skip filling those indices. 1520 1521 Inspired by the structured grid interface to the HYPRE package 1522 (http://www.llnl.gov/CASC/hypre) 1523 1524 Efficiency Alert: 1525 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1526 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1527 1528 Level: beginner 1529 1530 Concepts: matrices^putting entries in 1531 1532 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1533 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1534 @*/ 1535 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1536 { 1537 PetscErrorCode ierr; 1538 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1539 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1540 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1541 1542 PetscFunctionBegin; 1543 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1545 PetscValidType(mat,1); 1546 PetscValidIntPointer(idxm,3); 1547 PetscValidIntPointer(idxn,5); 1548 PetscValidScalarPointer(v,6); 1549 1550 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1551 jdxm = buf; jdxn = buf+m; 1552 } else { 1553 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1554 jdxm = bufm; jdxn = bufn; 1555 } 1556 for (i=0; i<m; i++) { 1557 for (j=0; j<3-sdim; j++) dxm++; 1558 tmp = *dxm++ - starts[0]; 1559 for (j=0; j<dim-1; j++) { 1560 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1561 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1562 } 1563 if (mat->stencil.noc) dxm++; 1564 jdxm[i] = tmp; 1565 } 1566 for (i=0; i<n; i++) { 1567 for (j=0; j<3-sdim; j++) dxn++; 1568 tmp = *dxn++ - starts[0]; 1569 for (j=0; j<dim-1; j++) { 1570 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1571 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1572 } 1573 if (mat->stencil.noc) dxn++; 1574 jdxn[i] = tmp; 1575 } 1576 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1577 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1578 PetscFunctionReturn(0); 1579 } 1580 1581 /*@ 1582 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1583 Using structured grid indexing 1584 1585 Not Collective 1586 1587 Input Parameters: 1588 + mat - the matrix 1589 . m - number of rows being entered 1590 . idxm - grid coordinates for matrix rows being entered 1591 . n - number of columns being entered 1592 . idxn - grid coordinates for matrix columns being entered 1593 . v - a logically two-dimensional array of values 1594 - addv - either ADD_VALUES or INSERT_VALUES, where 1595 ADD_VALUES adds values to any existing entries, and 1596 INSERT_VALUES replaces existing entries with new values 1597 1598 Notes: 1599 By default the values, v, are row-oriented and unsorted. 1600 See MatSetOption() for other options. 1601 1602 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1603 options cannot be mixed without intervening calls to the assembly 1604 routines. 1605 1606 The grid coordinates are across the entire grid, not just the local portion 1607 1608 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1609 as well as in C. 1610 1611 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1612 1613 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1614 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1615 1616 The columns and rows in the stencil passed in MUST be contained within the 1617 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1618 if you create a DMDA with an overlap of one grid level and on a particular process its first 1619 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1620 first i index you can use in your column and row indices in MatSetStencil() is 5. 1621 1622 In Fortran idxm and idxn should be declared as 1623 $ MatStencil idxm(4,m),idxn(4,n) 1624 and the values inserted using 1625 $ idxm(MatStencil_i,1) = i 1626 $ idxm(MatStencil_j,1) = j 1627 $ idxm(MatStencil_k,1) = k 1628 etc 1629 1630 Negative indices may be passed in idxm and idxn, these rows and columns are 1631 simply ignored. This allows easily inserting element stiffness matrices 1632 with homogeneous Dirchlet boundary conditions that you don't want represented 1633 in the matrix. 1634 1635 Inspired by the structured grid interface to the HYPRE package 1636 (http://www.llnl.gov/CASC/hypre) 1637 1638 Level: beginner 1639 1640 Concepts: matrices^putting entries in 1641 1642 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1643 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1644 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1645 @*/ 1646 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1647 { 1648 PetscErrorCode ierr; 1649 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1650 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1651 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1652 1653 PetscFunctionBegin; 1654 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1655 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1656 PetscValidType(mat,1); 1657 PetscValidIntPointer(idxm,3); 1658 PetscValidIntPointer(idxn,5); 1659 PetscValidScalarPointer(v,6); 1660 1661 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1662 jdxm = buf; jdxn = buf+m; 1663 } else { 1664 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1665 jdxm = bufm; jdxn = bufn; 1666 } 1667 for (i=0; i<m; i++) { 1668 for (j=0; j<3-sdim; j++) dxm++; 1669 tmp = *dxm++ - starts[0]; 1670 for (j=0; j<sdim-1; j++) { 1671 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1672 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1673 } 1674 dxm++; 1675 jdxm[i] = tmp; 1676 } 1677 for (i=0; i<n; i++) { 1678 for (j=0; j<3-sdim; j++) dxn++; 1679 tmp = *dxn++ - starts[0]; 1680 for (j=0; j<sdim-1; j++) { 1681 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1682 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1683 } 1684 dxn++; 1685 jdxn[i] = tmp; 1686 } 1687 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1688 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1689 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1690 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1691 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1692 } 1693 #endif 1694 PetscFunctionReturn(0); 1695 } 1696 1697 /*@ 1698 MatSetStencil - Sets the grid information for setting values into a matrix via 1699 MatSetValuesStencil() 1700 1701 Not Collective 1702 1703 Input Parameters: 1704 + mat - the matrix 1705 . dim - dimension of the grid 1, 2, or 3 1706 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1707 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1708 - dof - number of degrees of freedom per node 1709 1710 1711 Inspired by the structured grid interface to the HYPRE package 1712 (www.llnl.gov/CASC/hyper) 1713 1714 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1715 user. 1716 1717 Level: beginner 1718 1719 Concepts: matrices^putting entries in 1720 1721 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1722 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1723 @*/ 1724 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1725 { 1726 PetscInt i; 1727 1728 PetscFunctionBegin; 1729 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1730 PetscValidIntPointer(dims,3); 1731 PetscValidIntPointer(starts,4); 1732 1733 mat->stencil.dim = dim + (dof > 1); 1734 for (i=0; i<dim; i++) { 1735 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1736 mat->stencil.starts[i] = starts[dim-i-1]; 1737 } 1738 mat->stencil.dims[dim] = dof; 1739 mat->stencil.starts[dim] = 0; 1740 mat->stencil.noc = (PetscBool)(dof == 1); 1741 PetscFunctionReturn(0); 1742 } 1743 1744 /*@C 1745 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1746 1747 Not Collective 1748 1749 Input Parameters: 1750 + mat - the matrix 1751 . v - a logically two-dimensional array of values 1752 . m, idxm - the number of block rows and their global block indices 1753 . n, idxn - the number of block columns and their global block indices 1754 - addv - either ADD_VALUES or INSERT_VALUES, where 1755 ADD_VALUES adds values to any existing entries, and 1756 INSERT_VALUES replaces existing entries with new values 1757 1758 Notes: 1759 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1760 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1761 1762 The m and n count the NUMBER of blocks in the row direction and column direction, 1763 NOT the total number of rows/columns; for example, if the block size is 2 and 1764 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1765 The values in idxm would be 1 2; that is the first index for each block divided by 1766 the block size. 1767 1768 Note that you must call MatSetBlockSize() when constructing this matrix (before 1769 preallocating it). 1770 1771 By default the values, v, are row-oriented, so the layout of 1772 v is the same as for MatSetValues(). See MatSetOption() for other options. 1773 1774 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1775 options cannot be mixed without intervening calls to the assembly 1776 routines. 1777 1778 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1779 as well as in C. 1780 1781 Negative indices may be passed in idxm and idxn, these rows and columns are 1782 simply ignored. This allows easily inserting element stiffness matrices 1783 with homogeneous Dirchlet boundary conditions that you don't want represented 1784 in the matrix. 1785 1786 Each time an entry is set within a sparse matrix via MatSetValues(), 1787 internal searching must be done to determine where to place the 1788 data in the matrix storage space. By instead inserting blocks of 1789 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1790 reduced. 1791 1792 Example: 1793 $ Suppose m=n=2 and block size(bs) = 2 The array is 1794 $ 1795 $ 1 2 | 3 4 1796 $ 5 6 | 7 8 1797 $ - - - | - - - 1798 $ 9 10 | 11 12 1799 $ 13 14 | 15 16 1800 $ 1801 $ v[] should be passed in like 1802 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1803 $ 1804 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1805 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1806 1807 Level: intermediate 1808 1809 Concepts: matrices^putting entries in blocked 1810 1811 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1812 @*/ 1813 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1814 { 1815 PetscErrorCode ierr; 1816 1817 PetscFunctionBeginHot; 1818 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1819 PetscValidType(mat,1); 1820 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1821 PetscValidIntPointer(idxm,3); 1822 PetscValidIntPointer(idxn,5); 1823 PetscValidScalarPointer(v,6); 1824 MatCheckPreallocated(mat,1); 1825 if (mat->insertmode == NOT_SET_VALUES) { 1826 mat->insertmode = addv; 1827 } 1828 #if defined(PETSC_USE_DEBUG) 1829 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1830 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1831 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1832 #endif 1833 1834 if (mat->assembled) { 1835 mat->was_assembled = PETSC_TRUE; 1836 mat->assembled = PETSC_FALSE; 1837 } 1838 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1839 if (mat->ops->setvaluesblocked) { 1840 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1841 } else { 1842 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1843 PetscInt i,j,bs,cbs; 1844 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1845 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1846 iidxm = buf; iidxn = buf + m*bs; 1847 } else { 1848 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1849 iidxm = bufr; iidxn = bufc; 1850 } 1851 for (i=0; i<m; i++) { 1852 for (j=0; j<bs; j++) { 1853 iidxm[i*bs+j] = bs*idxm[i] + j; 1854 } 1855 } 1856 for (i=0; i<n; i++) { 1857 for (j=0; j<cbs; j++) { 1858 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1859 } 1860 } 1861 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1862 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1863 } 1864 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1865 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1866 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1867 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1868 } 1869 #endif 1870 PetscFunctionReturn(0); 1871 } 1872 1873 /*@ 1874 MatGetValues - Gets a block of values from a matrix. 1875 1876 Not Collective; currently only returns a local block 1877 1878 Input Parameters: 1879 + mat - the matrix 1880 . v - a logically two-dimensional array for storing the values 1881 . m, idxm - the number of rows and their global indices 1882 - n, idxn - the number of columns and their global indices 1883 1884 Notes: 1885 The user must allocate space (m*n PetscScalars) for the values, v. 1886 The values, v, are then returned in a row-oriented format, 1887 analogous to that used by default in MatSetValues(). 1888 1889 MatGetValues() uses 0-based row and column numbers in 1890 Fortran as well as in C. 1891 1892 MatGetValues() requires that the matrix has been assembled 1893 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1894 MatSetValues() and MatGetValues() CANNOT be made in succession 1895 without intermediate matrix assembly. 1896 1897 Negative row or column indices will be ignored and those locations in v[] will be 1898 left unchanged. 1899 1900 Level: advanced 1901 1902 Concepts: matrices^accessing values 1903 1904 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1905 @*/ 1906 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1907 { 1908 PetscErrorCode ierr; 1909 1910 PetscFunctionBegin; 1911 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1912 PetscValidType(mat,1); 1913 if (!m || !n) PetscFunctionReturn(0); 1914 PetscValidIntPointer(idxm,3); 1915 PetscValidIntPointer(idxn,5); 1916 PetscValidScalarPointer(v,6); 1917 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1918 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1919 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1920 MatCheckPreallocated(mat,1); 1921 1922 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1923 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1924 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1925 PetscFunctionReturn(0); 1926 } 1927 1928 /*@ 1929 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1930 the same size. Currently, this can only be called once and creates the given matrix. 1931 1932 Not Collective 1933 1934 Input Parameters: 1935 + mat - the matrix 1936 . nb - the number of blocks 1937 . bs - the number of rows (and columns) in each block 1938 . rows - a concatenation of the rows for each block 1939 - v - a concatenation of logically two-dimensional arrays of values 1940 1941 Notes: 1942 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1943 1944 Level: advanced 1945 1946 Concepts: matrices^putting entries in 1947 1948 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1949 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1950 @*/ 1951 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1952 { 1953 PetscErrorCode ierr; 1954 1955 PetscFunctionBegin; 1956 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1957 PetscValidType(mat,1); 1958 PetscValidScalarPointer(rows,4); 1959 PetscValidScalarPointer(v,5); 1960 #if defined(PETSC_USE_DEBUG) 1961 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1962 #endif 1963 1964 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1965 if (mat->ops->setvaluesbatch) { 1966 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1967 } else { 1968 PetscInt b; 1969 for (b = 0; b < nb; ++b) { 1970 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1971 } 1972 } 1973 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1974 PetscFunctionReturn(0); 1975 } 1976 1977 /*@ 1978 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 1979 the routine MatSetValuesLocal() to allow users to insert matrix entries 1980 using a local (per-processor) numbering. 1981 1982 Not Collective 1983 1984 Input Parameters: 1985 + x - the matrix 1986 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 1987 - cmapping - column mapping 1988 1989 Level: intermediate 1990 1991 Concepts: matrices^local to global mapping 1992 Concepts: local to global mapping^for matrices 1993 1994 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 1995 @*/ 1996 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1997 { 1998 PetscErrorCode ierr; 1999 2000 PetscFunctionBegin; 2001 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2002 PetscValidType(x,1); 2003 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2004 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2005 2006 if (x->ops->setlocaltoglobalmapping) { 2007 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2008 } else { 2009 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2010 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2011 } 2012 PetscFunctionReturn(0); 2013 } 2014 2015 2016 /*@ 2017 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2018 2019 Not Collective 2020 2021 Input Parameters: 2022 . A - the matrix 2023 2024 Output Parameters: 2025 + rmapping - row mapping 2026 - cmapping - column mapping 2027 2028 Level: advanced 2029 2030 Concepts: matrices^local to global mapping 2031 Concepts: local to global mapping^for matrices 2032 2033 .seealso: MatSetValuesLocal() 2034 @*/ 2035 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2036 { 2037 PetscFunctionBegin; 2038 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2039 PetscValidType(A,1); 2040 if (rmapping) PetscValidPointer(rmapping,2); 2041 if (cmapping) PetscValidPointer(cmapping,3); 2042 if (rmapping) *rmapping = A->rmap->mapping; 2043 if (cmapping) *cmapping = A->cmap->mapping; 2044 PetscFunctionReturn(0); 2045 } 2046 2047 /*@ 2048 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2049 2050 Not Collective 2051 2052 Input Parameters: 2053 . A - the matrix 2054 2055 Output Parameters: 2056 + rmap - row layout 2057 - cmap - column layout 2058 2059 Level: advanced 2060 2061 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2062 @*/ 2063 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2064 { 2065 PetscFunctionBegin; 2066 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2067 PetscValidType(A,1); 2068 if (rmap) PetscValidPointer(rmap,2); 2069 if (cmap) PetscValidPointer(cmap,3); 2070 if (rmap) *rmap = A->rmap; 2071 if (cmap) *cmap = A->cmap; 2072 PetscFunctionReturn(0); 2073 } 2074 2075 /*@C 2076 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2077 using a local ordering of the nodes. 2078 2079 Not Collective 2080 2081 Input Parameters: 2082 + mat - the matrix 2083 . nrow, irow - number of rows and their local indices 2084 . ncol, icol - number of columns and their local indices 2085 . y - a logically two-dimensional array of values 2086 - addv - either INSERT_VALUES or ADD_VALUES, where 2087 ADD_VALUES adds values to any existing entries, and 2088 INSERT_VALUES replaces existing entries with new values 2089 2090 Notes: 2091 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2092 MatSetUp() before using this routine 2093 2094 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2095 2096 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2097 options cannot be mixed without intervening calls to the assembly 2098 routines. 2099 2100 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2101 MUST be called after all calls to MatSetValuesLocal() have been completed. 2102 2103 Level: intermediate 2104 2105 Concepts: matrices^putting entries in with local numbering 2106 2107 Developer Notes: 2108 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2109 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2110 2111 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2112 MatSetValueLocal() 2113 @*/ 2114 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2115 { 2116 PetscErrorCode ierr; 2117 2118 PetscFunctionBeginHot; 2119 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2120 PetscValidType(mat,1); 2121 MatCheckPreallocated(mat,1); 2122 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2123 PetscValidIntPointer(irow,3); 2124 PetscValidIntPointer(icol,5); 2125 PetscValidScalarPointer(y,6); 2126 if (mat->insertmode == NOT_SET_VALUES) { 2127 mat->insertmode = addv; 2128 } 2129 #if defined(PETSC_USE_DEBUG) 2130 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2131 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2132 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2133 #endif 2134 2135 if (mat->assembled) { 2136 mat->was_assembled = PETSC_TRUE; 2137 mat->assembled = PETSC_FALSE; 2138 } 2139 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2140 if (mat->ops->setvalueslocal) { 2141 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2142 } else { 2143 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2144 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2145 irowm = buf; icolm = buf+nrow; 2146 } else { 2147 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2148 irowm = bufr; icolm = bufc; 2149 } 2150 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2151 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2152 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2153 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2154 } 2155 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2156 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2157 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2158 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2159 } 2160 #endif 2161 PetscFunctionReturn(0); 2162 } 2163 2164 /*@C 2165 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2166 using a local ordering of the nodes a block at a time. 2167 2168 Not Collective 2169 2170 Input Parameters: 2171 + x - the matrix 2172 . nrow, irow - number of rows and their local indices 2173 . ncol, icol - number of columns and their local indices 2174 . y - a logically two-dimensional array of values 2175 - addv - either INSERT_VALUES or ADD_VALUES, where 2176 ADD_VALUES adds values to any existing entries, and 2177 INSERT_VALUES replaces existing entries with new values 2178 2179 Notes: 2180 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2181 MatSetUp() before using this routine 2182 2183 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2184 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2185 2186 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2187 options cannot be mixed without intervening calls to the assembly 2188 routines. 2189 2190 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2191 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2192 2193 Level: intermediate 2194 2195 Developer Notes: 2196 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2197 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2198 2199 Concepts: matrices^putting blocked values in with local numbering 2200 2201 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2202 MatSetValuesLocal(), MatSetValuesBlocked() 2203 @*/ 2204 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2205 { 2206 PetscErrorCode ierr; 2207 2208 PetscFunctionBeginHot; 2209 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2210 PetscValidType(mat,1); 2211 MatCheckPreallocated(mat,1); 2212 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2213 PetscValidIntPointer(irow,3); 2214 PetscValidIntPointer(icol,5); 2215 PetscValidScalarPointer(y,6); 2216 if (mat->insertmode == NOT_SET_VALUES) { 2217 mat->insertmode = addv; 2218 } 2219 #if defined(PETSC_USE_DEBUG) 2220 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2221 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2222 if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2223 #endif 2224 2225 if (mat->assembled) { 2226 mat->was_assembled = PETSC_TRUE; 2227 mat->assembled = PETSC_FALSE; 2228 } 2229 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2230 if (mat->ops->setvaluesblockedlocal) { 2231 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2232 } else { 2233 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2234 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2235 irowm = buf; icolm = buf + nrow; 2236 } else { 2237 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2238 irowm = bufr; icolm = bufc; 2239 } 2240 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2241 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2242 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2243 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2244 } 2245 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2246 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2247 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2248 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2249 } 2250 #endif 2251 PetscFunctionReturn(0); 2252 } 2253 2254 /*@ 2255 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2256 2257 Collective on Mat and Vec 2258 2259 Input Parameters: 2260 + mat - the matrix 2261 - x - the vector to be multiplied 2262 2263 Output Parameters: 2264 . y - the result 2265 2266 Notes: 2267 The vectors x and y cannot be the same. I.e., one cannot 2268 call MatMult(A,y,y). 2269 2270 Level: developer 2271 2272 Concepts: matrix-vector product 2273 2274 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2275 @*/ 2276 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2277 { 2278 PetscErrorCode ierr; 2279 2280 PetscFunctionBegin; 2281 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2282 PetscValidType(mat,1); 2283 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2284 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2285 2286 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2287 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2288 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2289 MatCheckPreallocated(mat,1); 2290 2291 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2292 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2293 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2294 PetscFunctionReturn(0); 2295 } 2296 2297 /* --------------------------------------------------------*/ 2298 /*@ 2299 MatMult - Computes the matrix-vector product, y = Ax. 2300 2301 Neighbor-wise Collective on Mat and Vec 2302 2303 Input Parameters: 2304 + mat - the matrix 2305 - x - the vector to be multiplied 2306 2307 Output Parameters: 2308 . y - the result 2309 2310 Notes: 2311 The vectors x and y cannot be the same. I.e., one cannot 2312 call MatMult(A,y,y). 2313 2314 Level: beginner 2315 2316 Concepts: matrix-vector product 2317 2318 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2319 @*/ 2320 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2321 { 2322 PetscErrorCode ierr; 2323 2324 PetscFunctionBegin; 2325 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2326 PetscValidType(mat,1); 2327 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2328 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2329 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2330 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2331 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2332 #if !defined(PETSC_HAVE_CONSTRAINTS) 2333 if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2334 if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2335 if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n); 2336 #endif 2337 VecLocked(y,3); 2338 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2339 MatCheckPreallocated(mat,1); 2340 2341 ierr = VecLockPush(x);CHKERRQ(ierr); 2342 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2343 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2344 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2345 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2346 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2347 ierr = VecLockPop(x);CHKERRQ(ierr); 2348 PetscFunctionReturn(0); 2349 } 2350 2351 /*@ 2352 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2353 2354 Neighbor-wise Collective on Mat and Vec 2355 2356 Input Parameters: 2357 + mat - the matrix 2358 - x - the vector to be multiplied 2359 2360 Output Parameters: 2361 . y - the result 2362 2363 Notes: 2364 The vectors x and y cannot be the same. I.e., one cannot 2365 call MatMultTranspose(A,y,y). 2366 2367 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2368 use MatMultHermitianTranspose() 2369 2370 Level: beginner 2371 2372 Concepts: matrix vector product^transpose 2373 2374 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2375 @*/ 2376 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2377 { 2378 PetscErrorCode ierr; 2379 2380 PetscFunctionBegin; 2381 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2382 PetscValidType(mat,1); 2383 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2384 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2385 2386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2388 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2389 #if !defined(PETSC_HAVE_CONSTRAINTS) 2390 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 2391 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 2392 #endif 2393 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2394 MatCheckPreallocated(mat,1); 2395 2396 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2397 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2398 ierr = VecLockPush(x);CHKERRQ(ierr); 2399 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2400 ierr = VecLockPop(x);CHKERRQ(ierr); 2401 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2402 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2403 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2404 PetscFunctionReturn(0); 2405 } 2406 2407 /*@ 2408 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2409 2410 Neighbor-wise Collective on Mat and Vec 2411 2412 Input Parameters: 2413 + mat - the matrix 2414 - x - the vector to be multilplied 2415 2416 Output Parameters: 2417 . y - the result 2418 2419 Notes: 2420 The vectors x and y cannot be the same. I.e., one cannot 2421 call MatMultHermitianTranspose(A,y,y). 2422 2423 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2424 2425 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2426 2427 Level: beginner 2428 2429 Concepts: matrix vector product^transpose 2430 2431 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2432 @*/ 2433 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2434 { 2435 PetscErrorCode ierr; 2436 Vec w; 2437 2438 PetscFunctionBegin; 2439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2440 PetscValidType(mat,1); 2441 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2442 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2443 2444 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2445 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2446 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2447 #if !defined(PETSC_HAVE_CONSTRAINTS) 2448 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 2449 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 2450 #endif 2451 MatCheckPreallocated(mat,1); 2452 2453 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2454 if (mat->ops->multhermitiantranspose) { 2455 ierr = VecLockPush(x);CHKERRQ(ierr); 2456 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2457 ierr = VecLockPop(x);CHKERRQ(ierr); 2458 } else { 2459 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2460 ierr = VecCopy(x,w);CHKERRQ(ierr); 2461 ierr = VecConjugate(w);CHKERRQ(ierr); 2462 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2463 ierr = VecDestroy(&w);CHKERRQ(ierr); 2464 ierr = VecConjugate(y);CHKERRQ(ierr); 2465 } 2466 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2467 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2468 PetscFunctionReturn(0); 2469 } 2470 2471 /*@ 2472 MatMultAdd - Computes v3 = v2 + A * v1. 2473 2474 Neighbor-wise Collective on Mat and Vec 2475 2476 Input Parameters: 2477 + mat - the matrix 2478 - v1, v2 - the vectors 2479 2480 Output Parameters: 2481 . v3 - the result 2482 2483 Notes: 2484 The vectors v1 and v3 cannot be the same. I.e., one cannot 2485 call MatMultAdd(A,v1,v2,v1). 2486 2487 Level: beginner 2488 2489 Concepts: matrix vector product^addition 2490 2491 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2492 @*/ 2493 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2494 { 2495 PetscErrorCode ierr; 2496 2497 PetscFunctionBegin; 2498 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2499 PetscValidType(mat,1); 2500 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2501 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2502 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2503 2504 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2505 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2506 if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N); 2507 /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N); 2508 if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */ 2509 if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n); 2510 if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n); 2511 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2512 MatCheckPreallocated(mat,1); 2513 2514 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2515 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2516 ierr = VecLockPush(v1);CHKERRQ(ierr); 2517 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2518 ierr = VecLockPop(v1);CHKERRQ(ierr); 2519 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2520 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2521 PetscFunctionReturn(0); 2522 } 2523 2524 /*@ 2525 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2526 2527 Neighbor-wise Collective on Mat and Vec 2528 2529 Input Parameters: 2530 + mat - the matrix 2531 - v1, v2 - the vectors 2532 2533 Output Parameters: 2534 . v3 - the result 2535 2536 Notes: 2537 The vectors v1 and v3 cannot be the same. I.e., one cannot 2538 call MatMultTransposeAdd(A,v1,v2,v1). 2539 2540 Level: beginner 2541 2542 Concepts: matrix vector product^transpose and addition 2543 2544 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2545 @*/ 2546 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2547 { 2548 PetscErrorCode ierr; 2549 2550 PetscFunctionBegin; 2551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2552 PetscValidType(mat,1); 2553 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2554 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2555 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2556 2557 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2558 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2559 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2560 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2561 if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N); 2562 if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N); 2563 if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N); 2564 MatCheckPreallocated(mat,1); 2565 2566 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2567 ierr = VecLockPush(v1);CHKERRQ(ierr); 2568 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2569 ierr = VecLockPop(v1);CHKERRQ(ierr); 2570 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2571 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2572 PetscFunctionReturn(0); 2573 } 2574 2575 /*@ 2576 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2577 2578 Neighbor-wise Collective on Mat and Vec 2579 2580 Input Parameters: 2581 + mat - the matrix 2582 - v1, v2 - the vectors 2583 2584 Output Parameters: 2585 . v3 - the result 2586 2587 Notes: 2588 The vectors v1 and v3 cannot be the same. I.e., one cannot 2589 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2590 2591 Level: beginner 2592 2593 Concepts: matrix vector product^transpose and addition 2594 2595 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2596 @*/ 2597 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2598 { 2599 PetscErrorCode ierr; 2600 2601 PetscFunctionBegin; 2602 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2603 PetscValidType(mat,1); 2604 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2605 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2606 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2607 2608 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2609 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2610 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2611 if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N); 2612 if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N); 2613 if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N); 2614 MatCheckPreallocated(mat,1); 2615 2616 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2617 ierr = VecLockPush(v1);CHKERRQ(ierr); 2618 if (mat->ops->multhermitiantransposeadd) { 2619 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2620 } else { 2621 Vec w,z; 2622 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2623 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2624 ierr = VecConjugate(w);CHKERRQ(ierr); 2625 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2626 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2627 ierr = VecDestroy(&w);CHKERRQ(ierr); 2628 ierr = VecConjugate(z);CHKERRQ(ierr); 2629 if (v2 != v3) { 2630 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2631 } else { 2632 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2633 } 2634 ierr = VecDestroy(&z);CHKERRQ(ierr); 2635 } 2636 ierr = VecLockPop(v1);CHKERRQ(ierr); 2637 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2638 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2639 PetscFunctionReturn(0); 2640 } 2641 2642 /*@ 2643 MatMultConstrained - The inner multiplication routine for a 2644 constrained matrix P^T A P. 2645 2646 Neighbor-wise Collective on Mat and Vec 2647 2648 Input Parameters: 2649 + mat - the matrix 2650 - x - the vector to be multilplied 2651 2652 Output Parameters: 2653 . y - the result 2654 2655 Notes: 2656 The vectors x and y cannot be the same. I.e., one cannot 2657 call MatMult(A,y,y). 2658 2659 Level: beginner 2660 2661 .keywords: matrix, multiply, matrix-vector product, constraint 2662 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2663 @*/ 2664 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2665 { 2666 PetscErrorCode ierr; 2667 2668 PetscFunctionBegin; 2669 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2670 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2671 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2672 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2673 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2674 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2675 if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2676 if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2677 if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n); 2678 2679 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2680 ierr = VecLockPush(x);CHKERRQ(ierr); 2681 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2682 ierr = VecLockPop(x);CHKERRQ(ierr); 2683 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2684 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2685 PetscFunctionReturn(0); 2686 } 2687 2688 /*@ 2689 MatMultTransposeConstrained - The inner multiplication routine for a 2690 constrained matrix P^T A^T P. 2691 2692 Neighbor-wise Collective on Mat and Vec 2693 2694 Input Parameters: 2695 + mat - the matrix 2696 - x - the vector to be multilplied 2697 2698 Output Parameters: 2699 . y - the result 2700 2701 Notes: 2702 The vectors x and y cannot be the same. I.e., one cannot 2703 call MatMult(A,y,y). 2704 2705 Level: beginner 2706 2707 .keywords: matrix, multiply, matrix-vector product, constraint 2708 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2709 @*/ 2710 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2711 { 2712 PetscErrorCode ierr; 2713 2714 PetscFunctionBegin; 2715 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2716 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2717 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2718 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2719 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2720 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2721 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2722 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2723 2724 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2725 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2726 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2727 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2728 PetscFunctionReturn(0); 2729 } 2730 2731 /*@C 2732 MatGetFactorType - gets the type of factorization it is 2733 2734 Note Collective 2735 as the flag 2736 2737 Input Parameters: 2738 . mat - the matrix 2739 2740 Output Parameters: 2741 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2742 2743 Level: intermediate 2744 2745 .seealso: MatFactorType, MatGetFactor() 2746 @*/ 2747 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2748 { 2749 PetscFunctionBegin; 2750 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2751 PetscValidType(mat,1); 2752 *t = mat->factortype; 2753 PetscFunctionReturn(0); 2754 } 2755 2756 /* ------------------------------------------------------------*/ 2757 /*@C 2758 MatGetInfo - Returns information about matrix storage (number of 2759 nonzeros, memory, etc.). 2760 2761 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2762 2763 Input Parameters: 2764 . mat - the matrix 2765 2766 Output Parameters: 2767 + flag - flag indicating the type of parameters to be returned 2768 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2769 MAT_GLOBAL_SUM - sum over all processors) 2770 - info - matrix information context 2771 2772 Notes: 2773 The MatInfo context contains a variety of matrix data, including 2774 number of nonzeros allocated and used, number of mallocs during 2775 matrix assembly, etc. Additional information for factored matrices 2776 is provided (such as the fill ratio, number of mallocs during 2777 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2778 when using the runtime options 2779 $ -info -mat_view ::ascii_info 2780 2781 Example for C/C++ Users: 2782 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2783 data within the MatInfo context. For example, 2784 .vb 2785 MatInfo info; 2786 Mat A; 2787 double mal, nz_a, nz_u; 2788 2789 MatGetInfo(A,MAT_LOCAL,&info); 2790 mal = info.mallocs; 2791 nz_a = info.nz_allocated; 2792 .ve 2793 2794 Example for Fortran Users: 2795 Fortran users should declare info as a double precision 2796 array of dimension MAT_INFO_SIZE, and then extract the parameters 2797 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2798 a complete list of parameter names. 2799 .vb 2800 double precision info(MAT_INFO_SIZE) 2801 double precision mal, nz_a 2802 Mat A 2803 integer ierr 2804 2805 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2806 mal = info(MAT_INFO_MALLOCS) 2807 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2808 .ve 2809 2810 Level: intermediate 2811 2812 Concepts: matrices^getting information on 2813 2814 Developer Note: fortran interface is not autogenerated as the f90 2815 interface defintion cannot be generated correctly [due to MatInfo] 2816 2817 .seealso: MatStashGetInfo() 2818 2819 @*/ 2820 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2821 { 2822 PetscErrorCode ierr; 2823 2824 PetscFunctionBegin; 2825 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2826 PetscValidType(mat,1); 2827 PetscValidPointer(info,3); 2828 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2829 MatCheckPreallocated(mat,1); 2830 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2831 PetscFunctionReturn(0); 2832 } 2833 2834 /* 2835 This is used by external packages where it is not easy to get the info from the actual 2836 matrix factorization. 2837 */ 2838 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2839 { 2840 PetscErrorCode ierr; 2841 2842 PetscFunctionBegin; 2843 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2844 PetscFunctionReturn(0); 2845 } 2846 2847 /* ----------------------------------------------------------*/ 2848 2849 /*@C 2850 MatLUFactor - Performs in-place LU factorization of matrix. 2851 2852 Collective on Mat 2853 2854 Input Parameters: 2855 + mat - the matrix 2856 . row - row permutation 2857 . col - column permutation 2858 - info - options for factorization, includes 2859 $ fill - expected fill as ratio of original fill. 2860 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2861 $ Run with the option -info to determine an optimal value to use 2862 2863 Notes: 2864 Most users should employ the simplified KSP interface for linear solvers 2865 instead of working directly with matrix algebra routines such as this. 2866 See, e.g., KSPCreate(). 2867 2868 This changes the state of the matrix to a factored matrix; it cannot be used 2869 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2870 2871 Level: developer 2872 2873 Concepts: matrices^LU factorization 2874 2875 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2876 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2877 2878 Developer Note: fortran interface is not autogenerated as the f90 2879 interface defintion cannot be generated correctly [due to MatFactorInfo] 2880 2881 @*/ 2882 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2883 { 2884 PetscErrorCode ierr; 2885 MatFactorInfo tinfo; 2886 2887 PetscFunctionBegin; 2888 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2889 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2890 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2891 if (info) PetscValidPointer(info,4); 2892 PetscValidType(mat,1); 2893 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2894 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2895 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2896 MatCheckPreallocated(mat,1); 2897 if (!info) { 2898 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2899 info = &tinfo; 2900 } 2901 2902 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2903 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2904 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2905 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2906 PetscFunctionReturn(0); 2907 } 2908 2909 /*@C 2910 MatILUFactor - Performs in-place ILU factorization of matrix. 2911 2912 Collective on Mat 2913 2914 Input Parameters: 2915 + mat - the matrix 2916 . row - row permutation 2917 . col - column permutation 2918 - info - structure containing 2919 $ levels - number of levels of fill. 2920 $ expected fill - as ratio of original fill. 2921 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2922 missing diagonal entries) 2923 2924 Notes: 2925 Probably really in-place only when level of fill is zero, otherwise allocates 2926 new space to store factored matrix and deletes previous memory. 2927 2928 Most users should employ the simplified KSP interface for linear solvers 2929 instead of working directly with matrix algebra routines such as this. 2930 See, e.g., KSPCreate(). 2931 2932 Level: developer 2933 2934 Concepts: matrices^ILU factorization 2935 2936 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2937 2938 Developer Note: fortran interface is not autogenerated as the f90 2939 interface defintion cannot be generated correctly [due to MatFactorInfo] 2940 2941 @*/ 2942 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2943 { 2944 PetscErrorCode ierr; 2945 2946 PetscFunctionBegin; 2947 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2948 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2949 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2950 PetscValidPointer(info,4); 2951 PetscValidType(mat,1); 2952 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2953 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2954 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2955 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2956 MatCheckPreallocated(mat,1); 2957 2958 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2959 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2960 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2961 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2962 PetscFunctionReturn(0); 2963 } 2964 2965 /*@C 2966 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2967 Call this routine before calling MatLUFactorNumeric(). 2968 2969 Collective on Mat 2970 2971 Input Parameters: 2972 + fact - the factor matrix obtained with MatGetFactor() 2973 . mat - the matrix 2974 . row, col - row and column permutations 2975 - info - options for factorization, includes 2976 $ fill - expected fill as ratio of original fill. 2977 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2978 $ Run with the option -info to determine an optimal value to use 2979 2980 2981 Notes: 2982 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 2983 2984 Most users should employ the simplified KSP interface for linear solvers 2985 instead of working directly with matrix algebra routines such as this. 2986 See, e.g., KSPCreate(). 2987 2988 Level: developer 2989 2990 Concepts: matrices^LU symbolic factorization 2991 2992 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 2993 2994 Developer Note: fortran interface is not autogenerated as the f90 2995 interface defintion cannot be generated correctly [due to MatFactorInfo] 2996 2997 @*/ 2998 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 2999 { 3000 PetscErrorCode ierr; 3001 3002 PetscFunctionBegin; 3003 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3004 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3005 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3006 if (info) PetscValidPointer(info,4); 3007 PetscValidType(mat,1); 3008 PetscValidPointer(fact,5); 3009 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3010 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3011 if (!(fact)->ops->lufactorsymbolic) { 3012 MatSolverType spackage; 3013 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3014 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3015 } 3016 MatCheckPreallocated(mat,2); 3017 3018 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3019 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3020 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3021 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3022 PetscFunctionReturn(0); 3023 } 3024 3025 /*@C 3026 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3027 Call this routine after first calling MatLUFactorSymbolic(). 3028 3029 Collective on Mat 3030 3031 Input Parameters: 3032 + fact - the factor matrix obtained with MatGetFactor() 3033 . mat - the matrix 3034 - info - options for factorization 3035 3036 Notes: 3037 See MatLUFactor() for in-place factorization. See 3038 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3039 3040 Most users should employ the simplified KSP interface for linear solvers 3041 instead of working directly with matrix algebra routines such as this. 3042 See, e.g., KSPCreate(). 3043 3044 Level: developer 3045 3046 Concepts: matrices^LU numeric factorization 3047 3048 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3049 3050 Developer Note: fortran interface is not autogenerated as the f90 3051 interface defintion cannot be generated correctly [due to MatFactorInfo] 3052 3053 @*/ 3054 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3055 { 3056 PetscErrorCode ierr; 3057 3058 PetscFunctionBegin; 3059 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3060 PetscValidType(mat,1); 3061 PetscValidPointer(fact,2); 3062 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3063 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3064 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); 3065 3066 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3067 MatCheckPreallocated(mat,2); 3068 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3069 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3070 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3071 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3072 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3073 PetscFunctionReturn(0); 3074 } 3075 3076 /*@C 3077 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3078 symmetric matrix. 3079 3080 Collective on Mat 3081 3082 Input Parameters: 3083 + mat - the matrix 3084 . perm - row and column permutations 3085 - f - expected fill as ratio of original fill 3086 3087 Notes: 3088 See MatLUFactor() for the nonsymmetric case. See also 3089 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3090 3091 Most users should employ the simplified KSP interface for linear solvers 3092 instead of working directly with matrix algebra routines such as this. 3093 See, e.g., KSPCreate(). 3094 3095 Level: developer 3096 3097 Concepts: matrices^Cholesky factorization 3098 3099 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3100 MatGetOrdering() 3101 3102 Developer Note: fortran interface is not autogenerated as the f90 3103 interface defintion cannot be generated correctly [due to MatFactorInfo] 3104 3105 @*/ 3106 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3107 { 3108 PetscErrorCode ierr; 3109 3110 PetscFunctionBegin; 3111 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3112 PetscValidType(mat,1); 3113 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3114 if (info) PetscValidPointer(info,3); 3115 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3116 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3117 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3118 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); 3119 MatCheckPreallocated(mat,1); 3120 3121 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3122 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3123 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3124 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3125 PetscFunctionReturn(0); 3126 } 3127 3128 /*@C 3129 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3130 of a symmetric matrix. 3131 3132 Collective on Mat 3133 3134 Input Parameters: 3135 + fact - the factor matrix obtained with MatGetFactor() 3136 . mat - the matrix 3137 . perm - row and column permutations 3138 - info - options for factorization, includes 3139 $ fill - expected fill as ratio of original fill. 3140 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3141 $ Run with the option -info to determine an optimal value to use 3142 3143 Notes: 3144 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3145 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3146 3147 Most users should employ the simplified KSP interface for linear solvers 3148 instead of working directly with matrix algebra routines such as this. 3149 See, e.g., KSPCreate(). 3150 3151 Level: developer 3152 3153 Concepts: matrices^Cholesky symbolic factorization 3154 3155 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3156 MatGetOrdering() 3157 3158 Developer Note: fortran interface is not autogenerated as the f90 3159 interface defintion cannot be generated correctly [due to MatFactorInfo] 3160 3161 @*/ 3162 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3163 { 3164 PetscErrorCode ierr; 3165 3166 PetscFunctionBegin; 3167 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3168 PetscValidType(mat,1); 3169 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3170 if (info) PetscValidPointer(info,3); 3171 PetscValidPointer(fact,4); 3172 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3173 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3174 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3175 if (!(fact)->ops->choleskyfactorsymbolic) { 3176 MatSolverType spackage; 3177 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3178 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3179 } 3180 MatCheckPreallocated(mat,2); 3181 3182 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3183 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3184 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3185 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3186 PetscFunctionReturn(0); 3187 } 3188 3189 /*@C 3190 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3191 of a symmetric matrix. Call this routine after first calling 3192 MatCholeskyFactorSymbolic(). 3193 3194 Collective on Mat 3195 3196 Input Parameters: 3197 + fact - the factor matrix obtained with MatGetFactor() 3198 . mat - the initial matrix 3199 . info - options for factorization 3200 - fact - the symbolic factor of mat 3201 3202 3203 Notes: 3204 Most users should employ the simplified KSP interface for linear solvers 3205 instead of working directly with matrix algebra routines such as this. 3206 See, e.g., KSPCreate(). 3207 3208 Level: developer 3209 3210 Concepts: matrices^Cholesky numeric factorization 3211 3212 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3213 3214 Developer Note: fortran interface is not autogenerated as the f90 3215 interface defintion cannot be generated correctly [due to MatFactorInfo] 3216 3217 @*/ 3218 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3219 { 3220 PetscErrorCode ierr; 3221 3222 PetscFunctionBegin; 3223 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3224 PetscValidType(mat,1); 3225 PetscValidPointer(fact,2); 3226 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3227 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3228 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3229 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); 3230 MatCheckPreallocated(mat,2); 3231 3232 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3233 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3234 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3235 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3236 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3237 PetscFunctionReturn(0); 3238 } 3239 3240 /* ----------------------------------------------------------------*/ 3241 /*@ 3242 MatSolve - Solves A x = b, given a factored matrix. 3243 3244 Neighbor-wise Collective on Mat and Vec 3245 3246 Input Parameters: 3247 + mat - the factored matrix 3248 - b - the right-hand-side vector 3249 3250 Output Parameter: 3251 . x - the result vector 3252 3253 Notes: 3254 The vectors b and x cannot be the same. I.e., one cannot 3255 call MatSolve(A,x,x). 3256 3257 Notes: 3258 Most users should employ the simplified KSP interface for linear solvers 3259 instead of working directly with matrix algebra routines such as this. 3260 See, e.g., KSPCreate(). 3261 3262 Level: developer 3263 3264 Concepts: matrices^triangular solves 3265 3266 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3267 @*/ 3268 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3269 { 3270 PetscErrorCode ierr; 3271 3272 PetscFunctionBegin; 3273 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3274 PetscValidType(mat,1); 3275 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3276 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3277 PetscCheckSameComm(mat,1,b,2); 3278 PetscCheckSameComm(mat,1,x,3); 3279 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3280 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); 3281 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); 3282 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); 3283 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3284 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3285 MatCheckPreallocated(mat,1); 3286 3287 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3288 if (mat->factorerrortype) { 3289 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3290 ierr = VecSetInf(x);CHKERRQ(ierr); 3291 } else { 3292 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3293 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3294 } 3295 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3296 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3297 PetscFunctionReturn(0); 3298 } 3299 3300 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans) 3301 { 3302 PetscErrorCode ierr; 3303 Vec b,x; 3304 PetscInt m,N,i; 3305 PetscScalar *bb,*xx; 3306 PetscBool flg; 3307 3308 PetscFunctionBegin; 3309 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3310 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3311 ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3312 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 3313 3314 ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr); 3315 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3316 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3317 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3318 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3319 for (i=0; i<N; i++) { 3320 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3321 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3322 if (trans) { 3323 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3324 } else { 3325 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3326 } 3327 ierr = VecResetArray(x);CHKERRQ(ierr); 3328 ierr = VecResetArray(b);CHKERRQ(ierr); 3329 } 3330 ierr = VecDestroy(&b);CHKERRQ(ierr); 3331 ierr = VecDestroy(&x);CHKERRQ(ierr); 3332 ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr); 3333 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3334 PetscFunctionReturn(0); 3335 } 3336 3337 /*@ 3338 MatMatSolve - Solves A X = B, given a factored matrix. 3339 3340 Neighbor-wise Collective on Mat 3341 3342 Input Parameters: 3343 + A - the factored matrix 3344 - B - the right-hand-side matrix (dense matrix) 3345 3346 Output Parameter: 3347 . X - the result matrix (dense matrix) 3348 3349 Notes: 3350 The matrices b and x cannot be the same. I.e., one cannot 3351 call MatMatSolve(A,x,x). 3352 3353 Notes: 3354 Most users should usually employ the simplified KSP interface for linear solvers 3355 instead of working directly with matrix algebra routines such as this. 3356 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3357 at a time. 3358 3359 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3360 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3361 3362 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3363 3364 Level: developer 3365 3366 Concepts: matrices^triangular solves 3367 3368 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3369 @*/ 3370 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3371 { 3372 PetscErrorCode ierr; 3373 3374 PetscFunctionBegin; 3375 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3376 PetscValidType(A,1); 3377 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3378 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3379 PetscCheckSameComm(A,1,B,2); 3380 PetscCheckSameComm(A,1,X,3); 3381 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3382 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); 3383 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); 3384 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"); 3385 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3386 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3387 MatCheckPreallocated(A,1); 3388 3389 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3390 if (!A->ops->matsolve) { 3391 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3392 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3393 } else { 3394 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3395 } 3396 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3397 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3398 PetscFunctionReturn(0); 3399 } 3400 3401 /*@ 3402 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3403 3404 Neighbor-wise Collective on Mat 3405 3406 Input Parameters: 3407 + A - the factored matrix 3408 - B - the right-hand-side matrix (dense matrix) 3409 3410 Output Parameter: 3411 . X - the result matrix (dense matrix) 3412 3413 Notes: 3414 The matrices B and X cannot be the same. I.e., one cannot 3415 call MatMatSolveTranspose(A,X,X). 3416 3417 Notes: 3418 Most users should usually employ the simplified KSP interface for linear solvers 3419 instead of working directly with matrix algebra routines such as this. 3420 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3421 at a time. 3422 3423 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3424 3425 Level: developer 3426 3427 Concepts: matrices^triangular solves 3428 3429 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3430 @*/ 3431 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3432 { 3433 PetscErrorCode ierr; 3434 3435 PetscFunctionBegin; 3436 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3437 PetscValidType(A,1); 3438 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3439 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3440 PetscCheckSameComm(A,1,B,2); 3441 PetscCheckSameComm(A,1,X,3); 3442 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3443 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); 3444 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); 3445 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); 3446 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"); 3447 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3448 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3449 MatCheckPreallocated(A,1); 3450 3451 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3452 if (!A->ops->matsolvetranspose) { 3453 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3454 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3455 } else { 3456 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3457 } 3458 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3459 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3460 PetscFunctionReturn(0); 3461 } 3462 3463 /*@ 3464 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3465 3466 Neighbor-wise Collective on Mat 3467 3468 Input Parameters: 3469 + A - the factored matrix 3470 - Bt - the transpose of right-hand-side matrix 3471 3472 Output Parameter: 3473 . X - the result matrix (dense matrix) 3474 3475 Notes: 3476 Most users should usually employ the simplified KSP interface for linear solvers 3477 instead of working directly with matrix algebra routines such as this. 3478 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3479 at a time. 3480 3481 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(). 3482 3483 Level: developer 3484 3485 Concepts: matrices^triangular solves 3486 3487 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3488 @*/ 3489 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3490 { 3491 PetscErrorCode ierr; 3492 3493 PetscFunctionBegin; 3494 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3495 PetscValidType(A,1); 3496 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3497 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3498 PetscCheckSameComm(A,1,Bt,2); 3499 PetscCheckSameComm(A,1,X,3); 3500 3501 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3502 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); 3503 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); 3504 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"); 3505 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3506 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3507 MatCheckPreallocated(A,1); 3508 3509 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3510 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3511 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3512 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3513 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3514 PetscFunctionReturn(0); 3515 } 3516 3517 /*@ 3518 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3519 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3520 3521 Neighbor-wise Collective on Mat and Vec 3522 3523 Input Parameters: 3524 + mat - the factored matrix 3525 - b - the right-hand-side vector 3526 3527 Output Parameter: 3528 . x - the result vector 3529 3530 Notes: 3531 MatSolve() should be used for most applications, as it performs 3532 a forward solve followed by a backward solve. 3533 3534 The vectors b and x cannot be the same, i.e., one cannot 3535 call MatForwardSolve(A,x,x). 3536 3537 For matrix in seqsbaij format with block size larger than 1, 3538 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3539 MatForwardSolve() solves U^T*D y = b, and 3540 MatBackwardSolve() solves U x = y. 3541 Thus they do not provide a symmetric preconditioner. 3542 3543 Most users should employ the simplified KSP interface for linear solvers 3544 instead of working directly with matrix algebra routines such as this. 3545 See, e.g., KSPCreate(). 3546 3547 Level: developer 3548 3549 Concepts: matrices^forward solves 3550 3551 .seealso: MatSolve(), MatBackwardSolve() 3552 @*/ 3553 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3554 { 3555 PetscErrorCode ierr; 3556 3557 PetscFunctionBegin; 3558 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3559 PetscValidType(mat,1); 3560 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3561 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3562 PetscCheckSameComm(mat,1,b,2); 3563 PetscCheckSameComm(mat,1,x,3); 3564 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3565 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); 3566 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); 3567 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); 3568 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3569 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3570 MatCheckPreallocated(mat,1); 3571 3572 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3573 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3574 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3575 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3576 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3577 PetscFunctionReturn(0); 3578 } 3579 3580 /*@ 3581 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3582 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3583 3584 Neighbor-wise Collective on Mat and Vec 3585 3586 Input Parameters: 3587 + mat - the factored matrix 3588 - b - the right-hand-side vector 3589 3590 Output Parameter: 3591 . x - the result vector 3592 3593 Notes: 3594 MatSolve() should be used for most applications, as it performs 3595 a forward solve followed by a backward solve. 3596 3597 The vectors b and x cannot be the same. I.e., one cannot 3598 call MatBackwardSolve(A,x,x). 3599 3600 For matrix in seqsbaij format with block size larger than 1, 3601 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3602 MatForwardSolve() solves U^T*D y = b, and 3603 MatBackwardSolve() solves U x = y. 3604 Thus they do not provide a symmetric preconditioner. 3605 3606 Most users should employ the simplified KSP interface for linear solvers 3607 instead of working directly with matrix algebra routines such as this. 3608 See, e.g., KSPCreate(). 3609 3610 Level: developer 3611 3612 Concepts: matrices^backward solves 3613 3614 .seealso: MatSolve(), MatForwardSolve() 3615 @*/ 3616 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3617 { 3618 PetscErrorCode ierr; 3619 3620 PetscFunctionBegin; 3621 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3622 PetscValidType(mat,1); 3623 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3624 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3625 PetscCheckSameComm(mat,1,b,2); 3626 PetscCheckSameComm(mat,1,x,3); 3627 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3628 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); 3629 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); 3630 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); 3631 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3632 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3633 MatCheckPreallocated(mat,1); 3634 3635 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3636 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3637 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3638 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3639 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3640 PetscFunctionReturn(0); 3641 } 3642 3643 /*@ 3644 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3645 3646 Neighbor-wise Collective on Mat and Vec 3647 3648 Input Parameters: 3649 + mat - the factored matrix 3650 . b - the right-hand-side vector 3651 - y - the vector to be added to 3652 3653 Output Parameter: 3654 . x - the result vector 3655 3656 Notes: 3657 The vectors b and x cannot be the same. I.e., one cannot 3658 call MatSolveAdd(A,x,y,x). 3659 3660 Most users should employ the simplified KSP interface for linear solvers 3661 instead of working directly with matrix algebra routines such as this. 3662 See, e.g., KSPCreate(). 3663 3664 Level: developer 3665 3666 Concepts: matrices^triangular solves 3667 3668 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3669 @*/ 3670 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3671 { 3672 PetscScalar one = 1.0; 3673 Vec tmp; 3674 PetscErrorCode ierr; 3675 3676 PetscFunctionBegin; 3677 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3678 PetscValidType(mat,1); 3679 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3680 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3681 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3682 PetscCheckSameComm(mat,1,b,2); 3683 PetscCheckSameComm(mat,1,y,2); 3684 PetscCheckSameComm(mat,1,x,3); 3685 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3686 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); 3687 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); 3688 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); 3689 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); 3690 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); 3691 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3692 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3693 MatCheckPreallocated(mat,1); 3694 3695 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3696 if (mat->ops->solveadd) { 3697 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3698 } else { 3699 /* do the solve then the add manually */ 3700 if (x != y) { 3701 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3702 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3703 } else { 3704 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3705 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3706 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3707 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3708 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3709 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3710 } 3711 } 3712 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3713 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3714 PetscFunctionReturn(0); 3715 } 3716 3717 /*@ 3718 MatSolveTranspose - Solves A' x = 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 3726 Output Parameter: 3727 . x - the result vector 3728 3729 Notes: 3730 The vectors b and x cannot be the same. I.e., one cannot 3731 call MatSolveTranspose(A,x,x). 3732 3733 Most users should employ the simplified KSP interface for linear solvers 3734 instead of working directly with matrix algebra routines such as this. 3735 See, e.g., KSPCreate(). 3736 3737 Level: developer 3738 3739 Concepts: matrices^triangular solves 3740 3741 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3742 @*/ 3743 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3744 { 3745 PetscErrorCode ierr; 3746 3747 PetscFunctionBegin; 3748 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3749 PetscValidType(mat,1); 3750 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3751 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3752 PetscCheckSameComm(mat,1,b,2); 3753 PetscCheckSameComm(mat,1,x,3); 3754 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3755 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); 3756 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); 3757 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3758 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3759 MatCheckPreallocated(mat,1); 3760 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3761 if (mat->factorerrortype) { 3762 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3763 ierr = VecSetInf(x);CHKERRQ(ierr); 3764 } else { 3765 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3766 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3767 } 3768 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3769 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3770 PetscFunctionReturn(0); 3771 } 3772 3773 /*@ 3774 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3775 factored matrix. 3776 3777 Neighbor-wise Collective on Mat and Vec 3778 3779 Input Parameters: 3780 + mat - the factored matrix 3781 . b - the right-hand-side vector 3782 - y - the vector to be added to 3783 3784 Output Parameter: 3785 . x - the result vector 3786 3787 Notes: 3788 The vectors b and x cannot be the same. I.e., one cannot 3789 call MatSolveTransposeAdd(A,x,y,x). 3790 3791 Most users should employ the simplified KSP interface for linear solvers 3792 instead of working directly with matrix algebra routines such as this. 3793 See, e.g., KSPCreate(). 3794 3795 Level: developer 3796 3797 Concepts: matrices^triangular solves 3798 3799 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3800 @*/ 3801 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3802 { 3803 PetscScalar one = 1.0; 3804 PetscErrorCode ierr; 3805 Vec tmp; 3806 3807 PetscFunctionBegin; 3808 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3809 PetscValidType(mat,1); 3810 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3811 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3812 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3813 PetscCheckSameComm(mat,1,b,2); 3814 PetscCheckSameComm(mat,1,y,3); 3815 PetscCheckSameComm(mat,1,x,4); 3816 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3817 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); 3818 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); 3819 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); 3820 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); 3821 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3822 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3823 MatCheckPreallocated(mat,1); 3824 3825 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3826 if (mat->ops->solvetransposeadd) { 3827 if (mat->factorerrortype) { 3828 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3829 ierr = VecSetInf(x);CHKERRQ(ierr); 3830 } else { 3831 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3832 } 3833 } else { 3834 /* do the solve then the add manually */ 3835 if (x != y) { 3836 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3837 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3838 } else { 3839 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3840 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3841 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3842 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3843 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3844 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3845 } 3846 } 3847 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3848 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3849 PetscFunctionReturn(0); 3850 } 3851 /* ----------------------------------------------------------------*/ 3852 3853 /*@ 3854 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3855 3856 Neighbor-wise Collective on Mat and Vec 3857 3858 Input Parameters: 3859 + mat - the matrix 3860 . b - the right hand side 3861 . omega - the relaxation factor 3862 . flag - flag indicating the type of SOR (see below) 3863 . shift - diagonal shift 3864 . its - the number of iterations 3865 - lits - the number of local iterations 3866 3867 Output Parameters: 3868 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3869 3870 SOR Flags: 3871 . SOR_FORWARD_SWEEP - forward SOR 3872 . SOR_BACKWARD_SWEEP - backward SOR 3873 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3874 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3875 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3876 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3877 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3878 upper/lower triangular part of matrix to 3879 vector (with omega) 3880 . SOR_ZERO_INITIAL_GUESS - zero initial guess 3881 3882 Notes: 3883 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3884 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3885 on each processor. 3886 3887 Application programmers will not generally use MatSOR() directly, 3888 but instead will employ the KSP/PC interface. 3889 3890 Notes: 3891 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3892 3893 Notes for Advanced Users: 3894 The flags are implemented as bitwise inclusive or operations. 3895 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3896 to specify a zero initial guess for SSOR. 3897 3898 Most users should employ the simplified KSP interface for linear solvers 3899 instead of working directly with matrix algebra routines such as this. 3900 See, e.g., KSPCreate(). 3901 3902 Vectors x and b CANNOT be the same 3903 3904 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3905 3906 Level: developer 3907 3908 Concepts: matrices^relaxation 3909 Concepts: matrices^SOR 3910 Concepts: matrices^Gauss-Seidel 3911 3912 @*/ 3913 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3914 { 3915 PetscErrorCode ierr; 3916 3917 PetscFunctionBegin; 3918 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3919 PetscValidType(mat,1); 3920 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3921 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3922 PetscCheckSameComm(mat,1,b,2); 3923 PetscCheckSameComm(mat,1,x,8); 3924 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3925 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3926 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3927 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); 3928 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); 3929 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); 3930 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3931 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3932 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3933 3934 MatCheckPreallocated(mat,1); 3935 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3936 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3937 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3938 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3939 PetscFunctionReturn(0); 3940 } 3941 3942 /* 3943 Default matrix copy routine. 3944 */ 3945 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3946 { 3947 PetscErrorCode ierr; 3948 PetscInt i,rstart = 0,rend = 0,nz; 3949 const PetscInt *cwork; 3950 const PetscScalar *vwork; 3951 3952 PetscFunctionBegin; 3953 if (B->assembled) { 3954 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3955 } 3956 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3957 for (i=rstart; i<rend; i++) { 3958 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3959 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3960 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3961 } 3962 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3963 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3964 PetscFunctionReturn(0); 3965 } 3966 3967 /*@ 3968 MatCopy - Copys a matrix to another matrix. 3969 3970 Collective on Mat 3971 3972 Input Parameters: 3973 + A - the matrix 3974 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3975 3976 Output Parameter: 3977 . B - where the copy is put 3978 3979 Notes: 3980 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3981 same nonzero pattern or the routine will crash. 3982 3983 MatCopy() copies the matrix entries of a matrix to another existing 3984 matrix (after first zeroing the second matrix). A related routine is 3985 MatConvert(), which first creates a new matrix and then copies the data. 3986 3987 Level: intermediate 3988 3989 Concepts: matrices^copying 3990 3991 .seealso: MatConvert(), MatDuplicate() 3992 3993 @*/ 3994 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3995 { 3996 PetscErrorCode ierr; 3997 PetscInt i; 3998 3999 PetscFunctionBegin; 4000 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4001 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4002 PetscValidType(A,1); 4003 PetscValidType(B,2); 4004 PetscCheckSameComm(A,1,B,2); 4005 MatCheckPreallocated(B,2); 4006 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4007 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4008 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); 4009 MatCheckPreallocated(A,1); 4010 if (A == B) PetscFunctionReturn(0); 4011 4012 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4013 if (A->ops->copy) { 4014 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4015 } else { /* generic conversion */ 4016 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4017 } 4018 4019 B->stencil.dim = A->stencil.dim; 4020 B->stencil.noc = A->stencil.noc; 4021 for (i=0; i<=A->stencil.dim; i++) { 4022 B->stencil.dims[i] = A->stencil.dims[i]; 4023 B->stencil.starts[i] = A->stencil.starts[i]; 4024 } 4025 4026 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4027 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4028 PetscFunctionReturn(0); 4029 } 4030 4031 /*@C 4032 MatConvert - Converts a matrix to another matrix, either of the same 4033 or different type. 4034 4035 Collective on Mat 4036 4037 Input Parameters: 4038 + mat - the matrix 4039 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4040 same type as the original matrix. 4041 - reuse - denotes if the destination matrix is to be created or reused. 4042 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 4043 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). 4044 4045 Output Parameter: 4046 . M - pointer to place new matrix 4047 4048 Notes: 4049 MatConvert() first creates a new matrix and then copies the data from 4050 the first matrix. A related routine is MatCopy(), which copies the matrix 4051 entries of one matrix to another already existing matrix context. 4052 4053 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4054 the MPI communicator of the generated matrix is always the same as the communicator 4055 of the input matrix. 4056 4057 Level: intermediate 4058 4059 Concepts: matrices^converting between storage formats 4060 4061 .seealso: MatCopy(), MatDuplicate() 4062 @*/ 4063 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4064 { 4065 PetscErrorCode ierr; 4066 PetscBool sametype,issame,flg; 4067 char convname[256],mtype[256]; 4068 Mat B; 4069 4070 PetscFunctionBegin; 4071 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4072 PetscValidType(mat,1); 4073 PetscValidPointer(M,3); 4074 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4075 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4076 MatCheckPreallocated(mat,1); 4077 4078 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4079 if (flg) { 4080 newtype = mtype; 4081 } 4082 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4083 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4084 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4085 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"); 4086 4087 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 4088 4089 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4090 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4091 } else { 4092 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4093 const char *prefix[3] = {"seq","mpi",""}; 4094 PetscInt i; 4095 /* 4096 Order of precedence: 4097 1) See if a specialized converter is known to the current matrix. 4098 2) See if a specialized converter is known to the desired matrix class. 4099 3) See if a good general converter is registered for the desired class 4100 (as of 6/27/03 only MATMPIADJ falls into this category). 4101 4) See if a good general converter is known for the current matrix. 4102 5) Use a really basic converter. 4103 */ 4104 4105 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4106 for (i=0; i<3; i++) { 4107 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4108 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4109 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4110 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4111 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4112 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4113 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4114 if (conv) goto foundconv; 4115 } 4116 4117 /* 2) See if a specialized converter is known to the desired matrix class. */ 4118 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4119 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4120 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4121 for (i=0; i<3; i++) { 4122 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4123 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4124 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4125 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4126 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4127 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4128 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4129 if (conv) { 4130 ierr = MatDestroy(&B);CHKERRQ(ierr); 4131 goto foundconv; 4132 } 4133 } 4134 4135 /* 3) See if a good general converter is registered for the desired class */ 4136 conv = B->ops->convertfrom; 4137 ierr = MatDestroy(&B);CHKERRQ(ierr); 4138 if (conv) goto foundconv; 4139 4140 /* 4) See if a good general converter is known for the current matrix */ 4141 if (mat->ops->convert) { 4142 conv = mat->ops->convert; 4143 } 4144 if (conv) goto foundconv; 4145 4146 /* 5) Use a really basic converter. */ 4147 conv = MatConvert_Basic; 4148 4149 foundconv: 4150 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4151 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4152 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4153 /* the block sizes must be same if the mappings are copied over */ 4154 (*M)->rmap->bs = mat->rmap->bs; 4155 (*M)->cmap->bs = mat->cmap->bs; 4156 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4157 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4158 (*M)->rmap->mapping = mat->rmap->mapping; 4159 (*M)->cmap->mapping = mat->cmap->mapping; 4160 } 4161 (*M)->stencil.dim = mat->stencil.dim; 4162 (*M)->stencil.noc = mat->stencil.noc; 4163 for (i=0; i<=mat->stencil.dim; i++) { 4164 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4165 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4166 } 4167 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4168 } 4169 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4170 4171 /* Copy Mat options */ 4172 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4173 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4174 PetscFunctionReturn(0); 4175 } 4176 4177 /*@C 4178 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4179 4180 Not Collective 4181 4182 Input Parameter: 4183 . mat - the matrix, must be a factored matrix 4184 4185 Output Parameter: 4186 . type - the string name of the package (do not free this string) 4187 4188 Notes: 4189 In Fortran you pass in a empty string and the package name will be copied into it. 4190 (Make sure the string is long enough) 4191 4192 Level: intermediate 4193 4194 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4195 @*/ 4196 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4197 { 4198 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4199 4200 PetscFunctionBegin; 4201 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4202 PetscValidType(mat,1); 4203 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4204 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4205 if (!conv) { 4206 *type = MATSOLVERPETSC; 4207 } else { 4208 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4209 } 4210 PetscFunctionReturn(0); 4211 } 4212 4213 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4214 struct _MatSolverTypeForSpecifcType { 4215 MatType mtype; 4216 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4217 MatSolverTypeForSpecifcType next; 4218 }; 4219 4220 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4221 struct _MatSolverTypeHolder { 4222 char *name; 4223 MatSolverTypeForSpecifcType handlers; 4224 MatSolverTypeHolder next; 4225 }; 4226 4227 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4228 4229 /*@C 4230 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4231 4232 Input Parameters: 4233 + package - name of the package, for example petsc or superlu 4234 . mtype - the matrix type that works with this package 4235 . ftype - the type of factorization supported by the package 4236 - getfactor - routine that will create the factored matrix ready to be used 4237 4238 Level: intermediate 4239 4240 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4241 @*/ 4242 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4243 { 4244 PetscErrorCode ierr; 4245 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4246 PetscBool flg; 4247 MatSolverTypeForSpecifcType inext,iprev = NULL; 4248 4249 PetscFunctionBegin; 4250 ierr = MatInitializePackage();CHKERRQ(ierr); 4251 if (!next) { 4252 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4253 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4254 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4255 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4256 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4257 PetscFunctionReturn(0); 4258 } 4259 while (next) { 4260 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4261 if (flg) { 4262 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4263 inext = next->handlers; 4264 while (inext) { 4265 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4266 if (flg) { 4267 inext->getfactor[(int)ftype-1] = getfactor; 4268 PetscFunctionReturn(0); 4269 } 4270 iprev = inext; 4271 inext = inext->next; 4272 } 4273 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4274 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4275 iprev->next->getfactor[(int)ftype-1] = getfactor; 4276 PetscFunctionReturn(0); 4277 } 4278 prev = next; 4279 next = next->next; 4280 } 4281 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4282 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4283 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4284 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4285 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4286 PetscFunctionReturn(0); 4287 } 4288 4289 /*@C 4290 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4291 4292 Input Parameters: 4293 + package - name of the package, for example petsc or superlu 4294 . ftype - the type of factorization supported by the package 4295 - mtype - the matrix type that works with this package 4296 4297 Output Parameters: 4298 + foundpackage - PETSC_TRUE if the package was registered 4299 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4300 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4301 4302 Level: intermediate 4303 4304 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4305 @*/ 4306 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4307 { 4308 PetscErrorCode ierr; 4309 MatSolverTypeHolder next = MatSolverTypeHolders; 4310 PetscBool flg; 4311 MatSolverTypeForSpecifcType inext; 4312 4313 PetscFunctionBegin; 4314 if (foundpackage) *foundpackage = PETSC_FALSE; 4315 if (foundmtype) *foundmtype = PETSC_FALSE; 4316 if (getfactor) *getfactor = NULL; 4317 4318 if (package) { 4319 while (next) { 4320 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4321 if (flg) { 4322 if (foundpackage) *foundpackage = PETSC_TRUE; 4323 inext = next->handlers; 4324 while (inext) { 4325 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4326 if (flg) { 4327 if (foundmtype) *foundmtype = PETSC_TRUE; 4328 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4329 PetscFunctionReturn(0); 4330 } 4331 inext = inext->next; 4332 } 4333 } 4334 next = next->next; 4335 } 4336 } else { 4337 while (next) { 4338 inext = next->handlers; 4339 while (inext) { 4340 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4341 if (flg && inext->getfactor[(int)ftype-1]) { 4342 if (foundpackage) *foundpackage = PETSC_TRUE; 4343 if (foundmtype) *foundmtype = PETSC_TRUE; 4344 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4345 PetscFunctionReturn(0); 4346 } 4347 inext = inext->next; 4348 } 4349 next = next->next; 4350 } 4351 } 4352 PetscFunctionReturn(0); 4353 } 4354 4355 PetscErrorCode MatSolverTypeDestroy(void) 4356 { 4357 PetscErrorCode ierr; 4358 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4359 MatSolverTypeForSpecifcType inext,iprev; 4360 4361 PetscFunctionBegin; 4362 while (next) { 4363 ierr = PetscFree(next->name);CHKERRQ(ierr); 4364 inext = next->handlers; 4365 while (inext) { 4366 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4367 iprev = inext; 4368 inext = inext->next; 4369 ierr = PetscFree(iprev);CHKERRQ(ierr); 4370 } 4371 prev = next; 4372 next = next->next; 4373 ierr = PetscFree(prev);CHKERRQ(ierr); 4374 } 4375 MatSolverTypeHolders = NULL; 4376 PetscFunctionReturn(0); 4377 } 4378 4379 /*@C 4380 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4381 4382 Collective on Mat 4383 4384 Input Parameters: 4385 + mat - the matrix 4386 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4387 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4388 4389 Output Parameters: 4390 . f - the factor matrix used with MatXXFactorSymbolic() calls 4391 4392 Notes: 4393 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4394 such as pastix, superlu, mumps etc. 4395 4396 PETSc must have been ./configure to use the external solver, using the option --download-package 4397 4398 Level: intermediate 4399 4400 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4401 @*/ 4402 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4403 { 4404 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4405 PetscBool foundpackage,foundmtype; 4406 4407 PetscFunctionBegin; 4408 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4409 PetscValidType(mat,1); 4410 4411 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4412 MatCheckPreallocated(mat,1); 4413 4414 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4415 if (!foundpackage) { 4416 if (type) { 4417 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4418 } else { 4419 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4420 } 4421 } 4422 4423 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4424 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); 4425 4426 #if defined(PETSC_USE_COMPLEX) 4427 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"); 4428 #endif 4429 4430 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4431 PetscFunctionReturn(0); 4432 } 4433 4434 /*@C 4435 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4436 4437 Not Collective 4438 4439 Input Parameters: 4440 + mat - the matrix 4441 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4442 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4443 4444 Output Parameter: 4445 . flg - PETSC_TRUE if the factorization is available 4446 4447 Notes: 4448 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4449 such as pastix, superlu, mumps etc. 4450 4451 PETSc must have been ./configure to use the external solver, using the option --download-package 4452 4453 Level: intermediate 4454 4455 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4456 @*/ 4457 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4458 { 4459 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4460 4461 PetscFunctionBegin; 4462 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4463 PetscValidType(mat,1); 4464 4465 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4466 MatCheckPreallocated(mat,1); 4467 4468 *flg = PETSC_FALSE; 4469 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4470 if (gconv) { 4471 *flg = PETSC_TRUE; 4472 } 4473 PetscFunctionReturn(0); 4474 } 4475 4476 #include <petscdmtypes.h> 4477 4478 /*@ 4479 MatDuplicate - Duplicates a matrix including the non-zero structure. 4480 4481 Collective on Mat 4482 4483 Input Parameters: 4484 + mat - the matrix 4485 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4486 See the manual page for MatDuplicateOption for an explanation of these options. 4487 4488 Output Parameter: 4489 . M - pointer to place new matrix 4490 4491 Level: intermediate 4492 4493 Concepts: matrices^duplicating 4494 4495 Notes: 4496 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4497 4498 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4499 @*/ 4500 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4501 { 4502 PetscErrorCode ierr; 4503 Mat B; 4504 PetscInt i; 4505 DM dm; 4506 void (*viewf)(void); 4507 4508 PetscFunctionBegin; 4509 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4510 PetscValidType(mat,1); 4511 PetscValidPointer(M,3); 4512 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4513 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4514 MatCheckPreallocated(mat,1); 4515 4516 *M = 0; 4517 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4518 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4519 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4520 B = *M; 4521 4522 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4523 if (viewf) { 4524 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4525 } 4526 4527 B->stencil.dim = mat->stencil.dim; 4528 B->stencil.noc = mat->stencil.noc; 4529 for (i=0; i<=mat->stencil.dim; i++) { 4530 B->stencil.dims[i] = mat->stencil.dims[i]; 4531 B->stencil.starts[i] = mat->stencil.starts[i]; 4532 } 4533 4534 B->nooffproczerorows = mat->nooffproczerorows; 4535 B->nooffprocentries = mat->nooffprocentries; 4536 4537 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4538 if (dm) { 4539 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4540 } 4541 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4542 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4543 PetscFunctionReturn(0); 4544 } 4545 4546 /*@ 4547 MatGetDiagonal - Gets the diagonal of a matrix. 4548 4549 Logically Collective on Mat and Vec 4550 4551 Input Parameters: 4552 + mat - the matrix 4553 - v - the vector for storing the diagonal 4554 4555 Output Parameter: 4556 . v - the diagonal of the matrix 4557 4558 Level: intermediate 4559 4560 Note: 4561 Currently only correct in parallel for square matrices. 4562 4563 Concepts: matrices^accessing diagonals 4564 4565 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4566 @*/ 4567 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4568 { 4569 PetscErrorCode ierr; 4570 4571 PetscFunctionBegin; 4572 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4573 PetscValidType(mat,1); 4574 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4575 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4576 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4577 MatCheckPreallocated(mat,1); 4578 4579 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4580 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4581 PetscFunctionReturn(0); 4582 } 4583 4584 /*@C 4585 MatGetRowMin - Gets the minimum value (of the real part) of each 4586 row of the matrix 4587 4588 Logically Collective on Mat and Vec 4589 4590 Input Parameters: 4591 . mat - the matrix 4592 4593 Output Parameter: 4594 + v - the vector for storing the maximums 4595 - idx - the indices of the column found for each row (optional) 4596 4597 Level: intermediate 4598 4599 Notes: 4600 The result of this call are the same as if one converted the matrix to dense format 4601 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4602 4603 This code is only implemented for a couple of matrix formats. 4604 4605 Concepts: matrices^getting row maximums 4606 4607 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4608 MatGetRowMax() 4609 @*/ 4610 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4611 { 4612 PetscErrorCode ierr; 4613 4614 PetscFunctionBegin; 4615 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4616 PetscValidType(mat,1); 4617 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4618 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4619 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4620 MatCheckPreallocated(mat,1); 4621 4622 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4623 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4624 PetscFunctionReturn(0); 4625 } 4626 4627 /*@C 4628 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4629 row of the matrix 4630 4631 Logically Collective on Mat and Vec 4632 4633 Input Parameters: 4634 . mat - the matrix 4635 4636 Output Parameter: 4637 + v - the vector for storing the minimums 4638 - idx - the indices of the column found for each row (or NULL if not needed) 4639 4640 Level: intermediate 4641 4642 Notes: 4643 if a row is completely empty or has only 0.0 values then the idx[] value for that 4644 row is 0 (the first column). 4645 4646 This code is only implemented for a couple of matrix formats. 4647 4648 Concepts: matrices^getting row maximums 4649 4650 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4651 @*/ 4652 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4653 { 4654 PetscErrorCode ierr; 4655 4656 PetscFunctionBegin; 4657 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4658 PetscValidType(mat,1); 4659 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4660 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4661 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4662 MatCheckPreallocated(mat,1); 4663 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4664 4665 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4666 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4667 PetscFunctionReturn(0); 4668 } 4669 4670 /*@C 4671 MatGetRowMax - Gets the maximum value (of the real part) of each 4672 row of the matrix 4673 4674 Logically Collective on Mat and Vec 4675 4676 Input Parameters: 4677 . mat - the matrix 4678 4679 Output Parameter: 4680 + v - the vector for storing the maximums 4681 - idx - the indices of the column found for each row (optional) 4682 4683 Level: intermediate 4684 4685 Notes: 4686 The result of this call are the same as if one converted the matrix to dense format 4687 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4688 4689 This code is only implemented for a couple of matrix formats. 4690 4691 Concepts: matrices^getting row maximums 4692 4693 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4694 @*/ 4695 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4696 { 4697 PetscErrorCode ierr; 4698 4699 PetscFunctionBegin; 4700 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4701 PetscValidType(mat,1); 4702 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4703 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4704 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4705 MatCheckPreallocated(mat,1); 4706 4707 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4708 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4709 PetscFunctionReturn(0); 4710 } 4711 4712 /*@C 4713 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4714 row of the matrix 4715 4716 Logically Collective on Mat and Vec 4717 4718 Input Parameters: 4719 . mat - the matrix 4720 4721 Output Parameter: 4722 + v - the vector for storing the maximums 4723 - idx - the indices of the column found for each row (or NULL if not needed) 4724 4725 Level: intermediate 4726 4727 Notes: 4728 if a row is completely empty or has only 0.0 values then the idx[] value for that 4729 row is 0 (the first column). 4730 4731 This code is only implemented for a couple of matrix formats. 4732 4733 Concepts: matrices^getting row maximums 4734 4735 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4736 @*/ 4737 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4738 { 4739 PetscErrorCode ierr; 4740 4741 PetscFunctionBegin; 4742 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4743 PetscValidType(mat,1); 4744 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4745 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4746 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4747 MatCheckPreallocated(mat,1); 4748 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4749 4750 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4751 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4752 PetscFunctionReturn(0); 4753 } 4754 4755 /*@ 4756 MatGetRowSum - Gets the sum of each row of the matrix 4757 4758 Logically or Neighborhood Collective on Mat and Vec 4759 4760 Input Parameters: 4761 . mat - the matrix 4762 4763 Output Parameter: 4764 . v - the vector for storing the sum of rows 4765 4766 Level: intermediate 4767 4768 Notes: 4769 This code is slow since it is not currently specialized for different formats 4770 4771 Concepts: matrices^getting row sums 4772 4773 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4774 @*/ 4775 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4776 { 4777 Vec ones; 4778 PetscErrorCode ierr; 4779 4780 PetscFunctionBegin; 4781 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4782 PetscValidType(mat,1); 4783 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4784 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4785 MatCheckPreallocated(mat,1); 4786 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4787 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4788 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4789 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4790 PetscFunctionReturn(0); 4791 } 4792 4793 /*@ 4794 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4795 4796 Collective on Mat 4797 4798 Input Parameter: 4799 + mat - the matrix to transpose 4800 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4801 4802 Output Parameters: 4803 . B - the transpose 4804 4805 Notes: 4806 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4807 4808 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4809 4810 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4811 4812 Level: intermediate 4813 4814 Concepts: matrices^transposing 4815 4816 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4817 @*/ 4818 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4819 { 4820 PetscErrorCode ierr; 4821 4822 PetscFunctionBegin; 4823 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4824 PetscValidType(mat,1); 4825 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4826 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4827 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4828 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4829 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4830 MatCheckPreallocated(mat,1); 4831 4832 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4833 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4834 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4835 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4836 PetscFunctionReturn(0); 4837 } 4838 4839 /*@ 4840 MatIsTranspose - Test whether a matrix is another one's transpose, 4841 or its own, in which case it tests symmetry. 4842 4843 Collective on Mat 4844 4845 Input Parameter: 4846 + A - the matrix to test 4847 - B - the matrix to test against, this can equal the first parameter 4848 4849 Output Parameters: 4850 . flg - the result 4851 4852 Notes: 4853 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4854 has a running time of the order of the number of nonzeros; the parallel 4855 test involves parallel copies of the block-offdiagonal parts of the matrix. 4856 4857 Level: intermediate 4858 4859 Concepts: matrices^transposing, matrix^symmetry 4860 4861 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4862 @*/ 4863 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4864 { 4865 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4866 4867 PetscFunctionBegin; 4868 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4869 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4870 PetscValidPointer(flg,3); 4871 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4872 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4873 *flg = PETSC_FALSE; 4874 if (f && g) { 4875 if (f == g) { 4876 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4877 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4878 } else { 4879 MatType mattype; 4880 if (!f) { 4881 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4882 } else { 4883 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4884 } 4885 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4886 } 4887 PetscFunctionReturn(0); 4888 } 4889 4890 /*@ 4891 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4892 4893 Collective on Mat 4894 4895 Input Parameter: 4896 + mat - the matrix to transpose and complex conjugate 4897 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4898 4899 Output Parameters: 4900 . B - the Hermitian 4901 4902 Level: intermediate 4903 4904 Concepts: matrices^transposing, complex conjugatex 4905 4906 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4907 @*/ 4908 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4909 { 4910 PetscErrorCode ierr; 4911 4912 PetscFunctionBegin; 4913 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4914 #if defined(PETSC_USE_COMPLEX) 4915 ierr = MatConjugate(*B);CHKERRQ(ierr); 4916 #endif 4917 PetscFunctionReturn(0); 4918 } 4919 4920 /*@ 4921 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4922 4923 Collective on Mat 4924 4925 Input Parameter: 4926 + A - the matrix to test 4927 - B - the matrix to test against, this can equal the first parameter 4928 4929 Output Parameters: 4930 . flg - the result 4931 4932 Notes: 4933 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4934 has a running time of the order of the number of nonzeros; the parallel 4935 test involves parallel copies of the block-offdiagonal parts of the matrix. 4936 4937 Level: intermediate 4938 4939 Concepts: matrices^transposing, matrix^symmetry 4940 4941 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4942 @*/ 4943 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4944 { 4945 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4946 4947 PetscFunctionBegin; 4948 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4949 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4950 PetscValidPointer(flg,3); 4951 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4952 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4953 if (f && g) { 4954 if (f==g) { 4955 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4956 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4957 } 4958 PetscFunctionReturn(0); 4959 } 4960 4961 /*@ 4962 MatPermute - Creates a new matrix with rows and columns permuted from the 4963 original. 4964 4965 Collective on Mat 4966 4967 Input Parameters: 4968 + mat - the matrix to permute 4969 . row - row permutation, each processor supplies only the permutation for its rows 4970 - col - column permutation, each processor supplies only the permutation for its columns 4971 4972 Output Parameters: 4973 . B - the permuted matrix 4974 4975 Level: advanced 4976 4977 Note: 4978 The index sets map from row/col of permuted matrix to row/col of original matrix. 4979 The index sets should be on the same communicator as Mat and have the same local sizes. 4980 4981 Concepts: matrices^permuting 4982 4983 .seealso: MatGetOrdering(), ISAllGather() 4984 4985 @*/ 4986 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4987 { 4988 PetscErrorCode ierr; 4989 4990 PetscFunctionBegin; 4991 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4992 PetscValidType(mat,1); 4993 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4994 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4995 PetscValidPointer(B,4); 4996 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4997 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4998 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4999 MatCheckPreallocated(mat,1); 5000 5001 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5002 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5003 PetscFunctionReturn(0); 5004 } 5005 5006 /*@ 5007 MatEqual - Compares two matrices. 5008 5009 Collective on Mat 5010 5011 Input Parameters: 5012 + A - the first matrix 5013 - B - the second matrix 5014 5015 Output Parameter: 5016 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5017 5018 Level: intermediate 5019 5020 Concepts: matrices^equality between 5021 @*/ 5022 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5023 { 5024 PetscErrorCode ierr; 5025 5026 PetscFunctionBegin; 5027 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5028 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5029 PetscValidType(A,1); 5030 PetscValidType(B,2); 5031 PetscValidIntPointer(flg,3); 5032 PetscCheckSameComm(A,1,B,2); 5033 MatCheckPreallocated(B,2); 5034 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5035 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5036 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); 5037 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5038 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5039 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); 5040 MatCheckPreallocated(A,1); 5041 5042 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5043 PetscFunctionReturn(0); 5044 } 5045 5046 /*@ 5047 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5048 matrices that are stored as vectors. Either of the two scaling 5049 matrices can be NULL. 5050 5051 Collective on Mat 5052 5053 Input Parameters: 5054 + mat - the matrix to be scaled 5055 . l - the left scaling vector (or NULL) 5056 - r - the right scaling vector (or NULL) 5057 5058 Notes: 5059 MatDiagonalScale() computes A = LAR, where 5060 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5061 The L scales the rows of the matrix, the R scales the columns of the matrix. 5062 5063 Level: intermediate 5064 5065 Concepts: matrices^diagonal scaling 5066 Concepts: diagonal scaling of matrices 5067 5068 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5069 @*/ 5070 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5071 { 5072 PetscErrorCode ierr; 5073 5074 PetscFunctionBegin; 5075 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5076 PetscValidType(mat,1); 5077 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5078 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5079 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5080 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5081 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5082 MatCheckPreallocated(mat,1); 5083 5084 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5085 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5086 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5087 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5088 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5089 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5090 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5091 } 5092 #endif 5093 PetscFunctionReturn(0); 5094 } 5095 5096 /*@ 5097 MatScale - Scales all elements of a matrix by a given number. 5098 5099 Logically Collective on Mat 5100 5101 Input Parameters: 5102 + mat - the matrix to be scaled 5103 - a - the scaling value 5104 5105 Output Parameter: 5106 . mat - the scaled matrix 5107 5108 Level: intermediate 5109 5110 Concepts: matrices^scaling all entries 5111 5112 .seealso: MatDiagonalScale() 5113 @*/ 5114 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5115 { 5116 PetscErrorCode ierr; 5117 5118 PetscFunctionBegin; 5119 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5120 PetscValidType(mat,1); 5121 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5122 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5123 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5124 PetscValidLogicalCollectiveScalar(mat,a,2); 5125 MatCheckPreallocated(mat,1); 5126 5127 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5128 if (a != (PetscScalar)1.0) { 5129 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5130 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5131 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5132 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5133 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5134 } 5135 #endif 5136 } 5137 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5138 PetscFunctionReturn(0); 5139 } 5140 5141 static PetscErrorCode MatNorm_Basic(Mat A,NormType type,PetscReal *nrm) 5142 { 5143 PetscErrorCode ierr; 5144 5145 PetscFunctionBegin; 5146 if (type == NORM_1 || type == NORM_INFINITY) { 5147 Vec l,r; 5148 5149 ierr = MatCreateVecs(A,&r,&l);CHKERRQ(ierr); 5150 if (type == NORM_INFINITY) { 5151 ierr = VecSet(r,1.);CHKERRQ(ierr); 5152 ierr = MatMult(A,r,l);CHKERRQ(ierr); 5153 ierr = VecNorm(l,NORM_INFINITY,nrm);CHKERRQ(ierr); 5154 } else { 5155 ierr = VecSet(l,1.);CHKERRQ(ierr); 5156 ierr = MatMultTranspose(A,l,r);CHKERRQ(ierr); 5157 ierr = VecNorm(r,NORM_INFINITY,nrm);CHKERRQ(ierr); 5158 } 5159 ierr = VecDestroy(&l);CHKERRQ(ierr); 5160 ierr = VecDestroy(&r);CHKERRQ(ierr); 5161 } else SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix class %s, norm type %d",((PetscObject)A)->type_name,type); 5162 PetscFunctionReturn(0); 5163 } 5164 5165 /*@ 5166 MatNorm - Calculates various norms of a matrix. 5167 5168 Collective on Mat 5169 5170 Input Parameters: 5171 + mat - the matrix 5172 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5173 5174 Output Parameters: 5175 . nrm - the resulting norm 5176 5177 Level: intermediate 5178 5179 Concepts: matrices^norm 5180 Concepts: norm^of matrix 5181 @*/ 5182 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5183 { 5184 PetscErrorCode ierr; 5185 5186 PetscFunctionBegin; 5187 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5188 PetscValidType(mat,1); 5189 PetscValidLogicalCollectiveEnum(mat,type,2); 5190 PetscValidScalarPointer(nrm,3); 5191 5192 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5193 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5194 MatCheckPreallocated(mat,1); 5195 5196 if (!mat->ops->norm) { 5197 ierr = MatNorm_Basic(mat,type,nrm);CHKERRQ(ierr); 5198 } else { 5199 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5200 } 5201 PetscFunctionReturn(0); 5202 } 5203 5204 /* 5205 This variable is used to prevent counting of MatAssemblyBegin() that 5206 are called from within a MatAssemblyEnd(). 5207 */ 5208 static PetscInt MatAssemblyEnd_InUse = 0; 5209 /*@ 5210 MatAssemblyBegin - Begins assembling the matrix. This routine should 5211 be called after completing all calls to MatSetValues(). 5212 5213 Collective on Mat 5214 5215 Input Parameters: 5216 + mat - the matrix 5217 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5218 5219 Notes: 5220 MatSetValues() generally caches the values. The matrix is ready to 5221 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5222 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5223 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5224 using the matrix. 5225 5226 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5227 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 5228 a global collective operation requring all processes that share the matrix. 5229 5230 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5231 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5232 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5233 5234 Level: beginner 5235 5236 Concepts: matrices^assembling 5237 5238 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5239 @*/ 5240 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5241 { 5242 PetscErrorCode ierr; 5243 5244 PetscFunctionBegin; 5245 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5246 PetscValidType(mat,1); 5247 MatCheckPreallocated(mat,1); 5248 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5249 if (mat->assembled) { 5250 mat->was_assembled = PETSC_TRUE; 5251 mat->assembled = PETSC_FALSE; 5252 } 5253 if (!MatAssemblyEnd_InUse) { 5254 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5255 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5256 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5257 } else if (mat->ops->assemblybegin) { 5258 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5259 } 5260 PetscFunctionReturn(0); 5261 } 5262 5263 /*@ 5264 MatAssembled - Indicates if a matrix has been assembled and is ready for 5265 use; for example, in matrix-vector product. 5266 5267 Not Collective 5268 5269 Input Parameter: 5270 . mat - the matrix 5271 5272 Output Parameter: 5273 . assembled - PETSC_TRUE or PETSC_FALSE 5274 5275 Level: advanced 5276 5277 Concepts: matrices^assembled? 5278 5279 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5280 @*/ 5281 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5282 { 5283 PetscFunctionBegin; 5284 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5285 PetscValidType(mat,1); 5286 PetscValidPointer(assembled,2); 5287 *assembled = mat->assembled; 5288 PetscFunctionReturn(0); 5289 } 5290 5291 /*@ 5292 MatAssemblyEnd - Completes assembling the matrix. This routine should 5293 be called after MatAssemblyBegin(). 5294 5295 Collective on Mat 5296 5297 Input Parameters: 5298 + mat - the matrix 5299 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5300 5301 Options Database Keys: 5302 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5303 . -mat_view ::ascii_info_detail - Prints more detailed info 5304 . -mat_view - Prints matrix in ASCII format 5305 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5306 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5307 . -display <name> - Sets display name (default is host) 5308 . -draw_pause <sec> - Sets number of seconds to pause after display 5309 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5310 . -viewer_socket_machine <machine> - Machine to use for socket 5311 . -viewer_socket_port <port> - Port number to use for socket 5312 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5313 5314 Notes: 5315 MatSetValues() generally caches the values. The matrix is ready to 5316 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5317 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5318 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5319 using the matrix. 5320 5321 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5322 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5323 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5324 5325 Level: beginner 5326 5327 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5328 @*/ 5329 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5330 { 5331 PetscErrorCode ierr; 5332 static PetscInt inassm = 0; 5333 PetscBool flg = PETSC_FALSE; 5334 5335 PetscFunctionBegin; 5336 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5337 PetscValidType(mat,1); 5338 5339 inassm++; 5340 MatAssemblyEnd_InUse++; 5341 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5342 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5343 if (mat->ops->assemblyend) { 5344 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5345 } 5346 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5347 } else if (mat->ops->assemblyend) { 5348 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5349 } 5350 5351 /* Flush assembly is not a true assembly */ 5352 if (type != MAT_FLUSH_ASSEMBLY) { 5353 mat->assembled = PETSC_TRUE; mat->num_ass++; 5354 } 5355 mat->insertmode = NOT_SET_VALUES; 5356 MatAssemblyEnd_InUse--; 5357 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5358 if (!mat->symmetric_eternal) { 5359 mat->symmetric_set = PETSC_FALSE; 5360 mat->hermitian_set = PETSC_FALSE; 5361 mat->structurally_symmetric_set = PETSC_FALSE; 5362 } 5363 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5364 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5365 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5366 } 5367 #endif 5368 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5369 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5370 5371 if (mat->checksymmetryonassembly) { 5372 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5373 if (flg) { 5374 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5375 } else { 5376 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5377 } 5378 } 5379 if (mat->nullsp && mat->checknullspaceonassembly) { 5380 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5381 } 5382 } 5383 inassm--; 5384 PetscFunctionReturn(0); 5385 } 5386 5387 /*@ 5388 MatSetOption - Sets a parameter option for a matrix. Some options 5389 may be specific to certain storage formats. Some options 5390 determine how values will be inserted (or added). Sorted, 5391 row-oriented input will generally assemble the fastest. The default 5392 is row-oriented. 5393 5394 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5395 5396 Input Parameters: 5397 + mat - the matrix 5398 . option - the option, one of those listed below (and possibly others), 5399 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5400 5401 Options Describing Matrix Structure: 5402 + MAT_SPD - symmetric positive definite 5403 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5404 . MAT_HERMITIAN - transpose is the complex conjugation 5405 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5406 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5407 you set to be kept with all future use of the matrix 5408 including after MatAssemblyBegin/End() which could 5409 potentially change the symmetry structure, i.e. you 5410 KNOW the matrix will ALWAYS have the property you set. 5411 5412 5413 Options For Use with MatSetValues(): 5414 Insert a logically dense subblock, which can be 5415 . MAT_ROW_ORIENTED - row-oriented (default) 5416 5417 Note these options reflect the data you pass in with MatSetValues(); it has 5418 nothing to do with how the data is stored internally in the matrix 5419 data structure. 5420 5421 When (re)assembling a matrix, we can restrict the input for 5422 efficiency/debugging purposes. These options include: 5423 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5424 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5425 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5426 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5427 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5428 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5429 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5430 performance for very large process counts. 5431 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5432 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5433 functions, instead sending only neighbor messages. 5434 5435 Notes: 5436 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5437 5438 Some options are relevant only for particular matrix types and 5439 are thus ignored by others. Other options are not supported by 5440 certain matrix types and will generate an error message if set. 5441 5442 If using a Fortran 77 module to compute a matrix, one may need to 5443 use the column-oriented option (or convert to the row-oriented 5444 format). 5445 5446 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5447 that would generate a new entry in the nonzero structure is instead 5448 ignored. Thus, if memory has not alredy been allocated for this particular 5449 data, then the insertion is ignored. For dense matrices, in which 5450 the entire array is allocated, no entries are ever ignored. 5451 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5452 5453 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5454 that would generate a new entry in the nonzero structure instead produces 5455 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 5456 5457 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5458 that would generate a new entry that has not been preallocated will 5459 instead produce an error. (Currently supported for AIJ and BAIJ formats 5460 only.) This is a useful flag when debugging matrix memory preallocation. 5461 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5462 5463 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5464 other processors should be dropped, rather than stashed. 5465 This is useful if you know that the "owning" processor is also 5466 always generating the correct matrix entries, so that PETSc need 5467 not transfer duplicate entries generated on another processor. 5468 5469 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5470 searches during matrix assembly. When this flag is set, the hash table 5471 is created during the first Matrix Assembly. This hash table is 5472 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5473 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5474 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5475 supported by MATMPIBAIJ format only. 5476 5477 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5478 are kept in the nonzero structure 5479 5480 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5481 a zero location in the matrix 5482 5483 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5484 5485 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5486 zero row routines and thus improves performance for very large process counts. 5487 5488 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5489 part of the matrix (since they should match the upper triangular part). 5490 5491 Notes: 5492 Can only be called after MatSetSizes() and MatSetType() have been set. 5493 5494 Level: intermediate 5495 5496 Concepts: matrices^setting options 5497 5498 .seealso: MatOption, Mat 5499 5500 @*/ 5501 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5502 { 5503 PetscErrorCode ierr; 5504 5505 PetscFunctionBegin; 5506 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5507 PetscValidType(mat,1); 5508 if (op > 0) { 5509 PetscValidLogicalCollectiveEnum(mat,op,2); 5510 PetscValidLogicalCollectiveBool(mat,flg,3); 5511 } 5512 5513 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); 5514 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()"); 5515 5516 switch (op) { 5517 case MAT_NO_OFF_PROC_ENTRIES: 5518 mat->nooffprocentries = flg; 5519 PetscFunctionReturn(0); 5520 break; 5521 case MAT_SUBSET_OFF_PROC_ENTRIES: 5522 mat->subsetoffprocentries = flg; 5523 PetscFunctionReturn(0); 5524 case MAT_NO_OFF_PROC_ZERO_ROWS: 5525 mat->nooffproczerorows = flg; 5526 PetscFunctionReturn(0); 5527 break; 5528 case MAT_SPD: 5529 mat->spd_set = PETSC_TRUE; 5530 mat->spd = flg; 5531 if (flg) { 5532 mat->symmetric = PETSC_TRUE; 5533 mat->structurally_symmetric = PETSC_TRUE; 5534 mat->symmetric_set = PETSC_TRUE; 5535 mat->structurally_symmetric_set = PETSC_TRUE; 5536 } 5537 break; 5538 case MAT_SYMMETRIC: 5539 mat->symmetric = flg; 5540 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5541 mat->symmetric_set = PETSC_TRUE; 5542 mat->structurally_symmetric_set = flg; 5543 #if !defined(PETSC_USE_COMPLEX) 5544 mat->hermitian = flg; 5545 mat->hermitian_set = PETSC_TRUE; 5546 #endif 5547 break; 5548 case MAT_HERMITIAN: 5549 mat->hermitian = flg; 5550 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5551 mat->hermitian_set = PETSC_TRUE; 5552 mat->structurally_symmetric_set = flg; 5553 #if !defined(PETSC_USE_COMPLEX) 5554 mat->symmetric = flg; 5555 mat->symmetric_set = PETSC_TRUE; 5556 #endif 5557 break; 5558 case MAT_STRUCTURALLY_SYMMETRIC: 5559 mat->structurally_symmetric = flg; 5560 mat->structurally_symmetric_set = PETSC_TRUE; 5561 break; 5562 case MAT_SYMMETRY_ETERNAL: 5563 mat->symmetric_eternal = flg; 5564 break; 5565 case MAT_STRUCTURE_ONLY: 5566 mat->structure_only = flg; 5567 break; 5568 default: 5569 break; 5570 } 5571 if (mat->ops->setoption) { 5572 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5573 } 5574 PetscFunctionReturn(0); 5575 } 5576 5577 /*@ 5578 MatGetOption - Gets a parameter option that has been set for a matrix. 5579 5580 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5581 5582 Input Parameters: 5583 + mat - the matrix 5584 - option - the option, this only responds to certain options, check the code for which ones 5585 5586 Output Parameter: 5587 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5588 5589 Notes: 5590 Can only be called after MatSetSizes() and MatSetType() have been set. 5591 5592 Level: intermediate 5593 5594 Concepts: matrices^setting options 5595 5596 .seealso: MatOption, MatSetOption() 5597 5598 @*/ 5599 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5600 { 5601 PetscFunctionBegin; 5602 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5603 PetscValidType(mat,1); 5604 5605 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); 5606 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()"); 5607 5608 switch (op) { 5609 case MAT_NO_OFF_PROC_ENTRIES: 5610 *flg = mat->nooffprocentries; 5611 break; 5612 case MAT_NO_OFF_PROC_ZERO_ROWS: 5613 *flg = mat->nooffproczerorows; 5614 break; 5615 case MAT_SYMMETRIC: 5616 *flg = mat->symmetric; 5617 break; 5618 case MAT_HERMITIAN: 5619 *flg = mat->hermitian; 5620 break; 5621 case MAT_STRUCTURALLY_SYMMETRIC: 5622 *flg = mat->structurally_symmetric; 5623 break; 5624 case MAT_SYMMETRY_ETERNAL: 5625 *flg = mat->symmetric_eternal; 5626 break; 5627 case MAT_SPD: 5628 *flg = mat->spd; 5629 break; 5630 default: 5631 break; 5632 } 5633 PetscFunctionReturn(0); 5634 } 5635 5636 /*@ 5637 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5638 this routine retains the old nonzero structure. 5639 5640 Logically Collective on Mat 5641 5642 Input Parameters: 5643 . mat - the matrix 5644 5645 Level: intermediate 5646 5647 Notes: 5648 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. 5649 See the Performance chapter of the users manual for information on preallocating matrices. 5650 5651 Concepts: matrices^zeroing 5652 5653 .seealso: MatZeroRows() 5654 @*/ 5655 PetscErrorCode MatZeroEntries(Mat mat) 5656 { 5657 PetscErrorCode ierr; 5658 5659 PetscFunctionBegin; 5660 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5661 PetscValidType(mat,1); 5662 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5663 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"); 5664 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5665 MatCheckPreallocated(mat,1); 5666 5667 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5668 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5669 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5670 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5671 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5672 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5673 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5674 } 5675 #endif 5676 PetscFunctionReturn(0); 5677 } 5678 5679 /*@ 5680 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5681 of a set of rows and columns of a matrix. 5682 5683 Collective on Mat 5684 5685 Input Parameters: 5686 + mat - the matrix 5687 . numRows - the number of rows to remove 5688 . rows - the global row indices 5689 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5690 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5691 - b - optional vector of right hand side, that will be adjusted by provided solution 5692 5693 Notes: 5694 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5695 5696 The user can set a value in the diagonal entry (or for the AIJ and 5697 row formats can optionally remove the main diagonal entry from the 5698 nonzero structure as well, by passing 0.0 as the final argument). 5699 5700 For the parallel case, all processes that share the matrix (i.e., 5701 those in the communicator used for matrix creation) MUST call this 5702 routine, regardless of whether any rows being zeroed are owned by 5703 them. 5704 5705 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5706 list only rows local to itself). 5707 5708 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5709 5710 Level: intermediate 5711 5712 Concepts: matrices^zeroing rows 5713 5714 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5715 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5716 @*/ 5717 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5718 { 5719 PetscErrorCode ierr; 5720 5721 PetscFunctionBegin; 5722 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5723 PetscValidType(mat,1); 5724 if (numRows) PetscValidIntPointer(rows,3); 5725 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5726 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5727 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5728 MatCheckPreallocated(mat,1); 5729 5730 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5731 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5732 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5733 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5734 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5735 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5736 } 5737 #endif 5738 PetscFunctionReturn(0); 5739 } 5740 5741 /*@ 5742 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5743 of a set of rows and columns of a matrix. 5744 5745 Collective on Mat 5746 5747 Input Parameters: 5748 + mat - the matrix 5749 . is - the rows to zero 5750 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5751 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5752 - b - optional vector of right hand side, that will be adjusted by provided solution 5753 5754 Notes: 5755 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5756 5757 The user can set a value in the diagonal entry (or for the AIJ and 5758 row formats can optionally remove the main diagonal entry from the 5759 nonzero structure as well, by passing 0.0 as the final argument). 5760 5761 For the parallel case, all processes that share the matrix (i.e., 5762 those in the communicator used for matrix creation) MUST call this 5763 routine, regardless of whether any rows being zeroed are owned by 5764 them. 5765 5766 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5767 list only rows local to itself). 5768 5769 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5770 5771 Level: intermediate 5772 5773 Concepts: matrices^zeroing rows 5774 5775 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5776 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5777 @*/ 5778 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5779 { 5780 PetscErrorCode ierr; 5781 PetscInt numRows; 5782 const PetscInt *rows; 5783 5784 PetscFunctionBegin; 5785 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5786 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5787 PetscValidType(mat,1); 5788 PetscValidType(is,2); 5789 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5790 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5791 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5792 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5793 PetscFunctionReturn(0); 5794 } 5795 5796 /*@ 5797 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5798 of a set of rows of a matrix. 5799 5800 Collective on Mat 5801 5802 Input Parameters: 5803 + mat - the matrix 5804 . numRows - the number of rows to remove 5805 . rows - the global row indices 5806 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5807 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5808 - b - optional vector of right hand side, that will be adjusted by provided solution 5809 5810 Notes: 5811 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5812 but does not release memory. For the dense and block diagonal 5813 formats this does not alter the nonzero structure. 5814 5815 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5816 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5817 merely zeroed. 5818 5819 The user can set a value in the diagonal entry (or for the AIJ and 5820 row formats can optionally remove the main diagonal entry from the 5821 nonzero structure as well, by passing 0.0 as the final argument). 5822 5823 For the parallel case, all processes that share the matrix (i.e., 5824 those in the communicator used for matrix creation) MUST call this 5825 routine, regardless of whether any rows being zeroed are owned by 5826 them. 5827 5828 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5829 list only rows local to itself). 5830 5831 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5832 owns that are to be zeroed. This saves a global synchronization in the implementation. 5833 5834 Level: intermediate 5835 5836 Concepts: matrices^zeroing rows 5837 5838 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5839 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5840 @*/ 5841 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5842 { 5843 PetscErrorCode ierr; 5844 5845 PetscFunctionBegin; 5846 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5847 PetscValidType(mat,1); 5848 if (numRows) PetscValidIntPointer(rows,3); 5849 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5850 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5851 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5852 MatCheckPreallocated(mat,1); 5853 5854 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5855 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5856 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5857 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5858 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5859 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5860 } 5861 #endif 5862 PetscFunctionReturn(0); 5863 } 5864 5865 /*@ 5866 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5867 of a set of rows of a matrix. 5868 5869 Collective on Mat 5870 5871 Input Parameters: 5872 + mat - the matrix 5873 . is - index set of rows to remove 5874 . diag - value put in all diagonals of eliminated rows 5875 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5876 - b - optional vector of right hand side, that will be adjusted by provided solution 5877 5878 Notes: 5879 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5880 but does not release memory. For the dense and block diagonal 5881 formats this does not alter the nonzero structure. 5882 5883 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5884 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5885 merely zeroed. 5886 5887 The user can set a value in the diagonal entry (or for the AIJ and 5888 row formats can optionally remove the main diagonal entry from the 5889 nonzero structure as well, by passing 0.0 as the final argument). 5890 5891 For the parallel case, all processes that share the matrix (i.e., 5892 those in the communicator used for matrix creation) MUST call this 5893 routine, regardless of whether any rows being zeroed are owned by 5894 them. 5895 5896 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5897 list only rows local to itself). 5898 5899 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5900 owns that are to be zeroed. This saves a global synchronization in the implementation. 5901 5902 Level: intermediate 5903 5904 Concepts: matrices^zeroing rows 5905 5906 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5907 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5908 @*/ 5909 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5910 { 5911 PetscInt numRows; 5912 const PetscInt *rows; 5913 PetscErrorCode ierr; 5914 5915 PetscFunctionBegin; 5916 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5917 PetscValidType(mat,1); 5918 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5919 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5920 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5921 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5922 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5923 PetscFunctionReturn(0); 5924 } 5925 5926 /*@ 5927 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5928 of a set of rows of a matrix. These rows must be local to the process. 5929 5930 Collective on Mat 5931 5932 Input Parameters: 5933 + mat - the matrix 5934 . numRows - the number of rows to remove 5935 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5936 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5937 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5938 - b - optional vector of right hand side, that will be adjusted by provided solution 5939 5940 Notes: 5941 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5942 but does not release memory. For the dense and block diagonal 5943 formats this does not alter the nonzero structure. 5944 5945 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5946 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5947 merely zeroed. 5948 5949 The user can set a value in the diagonal entry (or for the AIJ and 5950 row formats can optionally remove the main diagonal entry from the 5951 nonzero structure as well, by passing 0.0 as the final argument). 5952 5953 For the parallel case, all processes that share the matrix (i.e., 5954 those in the communicator used for matrix creation) MUST call this 5955 routine, regardless of whether any rows being zeroed are owned by 5956 them. 5957 5958 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5959 list only rows local to itself). 5960 5961 The grid coordinates are across the entire grid, not just the local portion 5962 5963 In Fortran idxm and idxn should be declared as 5964 $ MatStencil idxm(4,m) 5965 and the values inserted using 5966 $ idxm(MatStencil_i,1) = i 5967 $ idxm(MatStencil_j,1) = j 5968 $ idxm(MatStencil_k,1) = k 5969 $ idxm(MatStencil_c,1) = c 5970 etc 5971 5972 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5973 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5974 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5975 DM_BOUNDARY_PERIODIC boundary type. 5976 5977 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 5978 a single value per point) you can skip filling those indices. 5979 5980 Level: intermediate 5981 5982 Concepts: matrices^zeroing rows 5983 5984 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5985 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5986 @*/ 5987 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5988 { 5989 PetscInt dim = mat->stencil.dim; 5990 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5991 PetscInt *dims = mat->stencil.dims+1; 5992 PetscInt *starts = mat->stencil.starts; 5993 PetscInt *dxm = (PetscInt*) rows; 5994 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5995 PetscErrorCode ierr; 5996 5997 PetscFunctionBegin; 5998 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5999 PetscValidType(mat,1); 6000 if (numRows) PetscValidIntPointer(rows,3); 6001 6002 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6003 for (i = 0; i < numRows; ++i) { 6004 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6005 for (j = 0; j < 3-sdim; ++j) dxm++; 6006 /* Local index in X dir */ 6007 tmp = *dxm++ - starts[0]; 6008 /* Loop over remaining dimensions */ 6009 for (j = 0; j < dim-1; ++j) { 6010 /* If nonlocal, set index to be negative */ 6011 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6012 /* Update local index */ 6013 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6014 } 6015 /* Skip component slot if necessary */ 6016 if (mat->stencil.noc) dxm++; 6017 /* Local row number */ 6018 if (tmp >= 0) { 6019 jdxm[numNewRows++] = tmp; 6020 } 6021 } 6022 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6023 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6024 PetscFunctionReturn(0); 6025 } 6026 6027 /*@ 6028 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6029 of a set of rows and columns of a matrix. 6030 6031 Collective on Mat 6032 6033 Input Parameters: 6034 + mat - the matrix 6035 . numRows - the number of rows/columns to remove 6036 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6037 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6038 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6039 - b - optional vector of right hand side, that will be adjusted by provided solution 6040 6041 Notes: 6042 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6043 but does not release memory. For the dense and block diagonal 6044 formats this does not alter the nonzero structure. 6045 6046 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6047 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6048 merely zeroed. 6049 6050 The user can set a value in the diagonal entry (or for the AIJ and 6051 row formats can optionally remove the main diagonal entry from the 6052 nonzero structure as well, by passing 0.0 as the final argument). 6053 6054 For the parallel case, all processes that share the matrix (i.e., 6055 those in the communicator used for matrix creation) MUST call this 6056 routine, regardless of whether any rows being zeroed are owned by 6057 them. 6058 6059 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6060 list only rows local to itself, but the row/column numbers are given in local numbering). 6061 6062 The grid coordinates are across the entire grid, not just the local portion 6063 6064 In Fortran idxm and idxn should be declared as 6065 $ MatStencil idxm(4,m) 6066 and the values inserted using 6067 $ idxm(MatStencil_i,1) = i 6068 $ idxm(MatStencil_j,1) = j 6069 $ idxm(MatStencil_k,1) = k 6070 $ idxm(MatStencil_c,1) = c 6071 etc 6072 6073 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6074 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6075 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6076 DM_BOUNDARY_PERIODIC boundary type. 6077 6078 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 6079 a single value per point) you can skip filling those indices. 6080 6081 Level: intermediate 6082 6083 Concepts: matrices^zeroing rows 6084 6085 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6086 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6087 @*/ 6088 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6089 { 6090 PetscInt dim = mat->stencil.dim; 6091 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6092 PetscInt *dims = mat->stencil.dims+1; 6093 PetscInt *starts = mat->stencil.starts; 6094 PetscInt *dxm = (PetscInt*) rows; 6095 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6096 PetscErrorCode ierr; 6097 6098 PetscFunctionBegin; 6099 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6100 PetscValidType(mat,1); 6101 if (numRows) PetscValidIntPointer(rows,3); 6102 6103 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6104 for (i = 0; i < numRows; ++i) { 6105 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6106 for (j = 0; j < 3-sdim; ++j) dxm++; 6107 /* Local index in X dir */ 6108 tmp = *dxm++ - starts[0]; 6109 /* Loop over remaining dimensions */ 6110 for (j = 0; j < dim-1; ++j) { 6111 /* If nonlocal, set index to be negative */ 6112 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6113 /* Update local index */ 6114 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6115 } 6116 /* Skip component slot if necessary */ 6117 if (mat->stencil.noc) dxm++; 6118 /* Local row number */ 6119 if (tmp >= 0) { 6120 jdxm[numNewRows++] = tmp; 6121 } 6122 } 6123 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6124 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6125 PetscFunctionReturn(0); 6126 } 6127 6128 /*@C 6129 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6130 of a set of rows of a matrix; using local numbering of rows. 6131 6132 Collective on Mat 6133 6134 Input Parameters: 6135 + mat - the matrix 6136 . numRows - the number of rows to remove 6137 . rows - the global row indices 6138 . diag - value put in all diagonals of eliminated rows 6139 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6140 - b - optional vector of right hand side, that will be adjusted by provided solution 6141 6142 Notes: 6143 Before calling MatZeroRowsLocal(), the user must first set the 6144 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6145 6146 For the AIJ matrix formats this removes the old nonzero structure, 6147 but does not release memory. For the dense and block diagonal 6148 formats this does not alter the nonzero structure. 6149 6150 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6151 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6152 merely zeroed. 6153 6154 The user can set a value in the diagonal entry (or for the AIJ and 6155 row formats can optionally remove the main diagonal entry from the 6156 nonzero structure as well, by passing 0.0 as the final argument). 6157 6158 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6159 owns that are to be zeroed. This saves a global synchronization in the implementation. 6160 6161 Level: intermediate 6162 6163 Concepts: matrices^zeroing 6164 6165 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6166 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6167 @*/ 6168 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6169 { 6170 PetscErrorCode ierr; 6171 6172 PetscFunctionBegin; 6173 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6174 PetscValidType(mat,1); 6175 if (numRows) PetscValidIntPointer(rows,3); 6176 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6177 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6178 MatCheckPreallocated(mat,1); 6179 6180 if (mat->ops->zerorowslocal) { 6181 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6182 } else { 6183 IS is, newis; 6184 const PetscInt *newRows; 6185 6186 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6187 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6188 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6189 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6190 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6191 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6192 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6193 ierr = ISDestroy(&is);CHKERRQ(ierr); 6194 } 6195 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6196 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6197 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6198 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6199 } 6200 #endif 6201 PetscFunctionReturn(0); 6202 } 6203 6204 /*@ 6205 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6206 of a set of rows of a matrix; using local numbering of rows. 6207 6208 Collective on Mat 6209 6210 Input Parameters: 6211 + mat - the matrix 6212 . is - index set of rows to remove 6213 . diag - value put in all diagonals of eliminated rows 6214 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6215 - b - optional vector of right hand side, that will be adjusted by provided solution 6216 6217 Notes: 6218 Before calling MatZeroRowsLocalIS(), the user must first set the 6219 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6220 6221 For the AIJ matrix formats this removes the old nonzero structure, 6222 but does not release memory. For the dense and block diagonal 6223 formats this does not alter the nonzero structure. 6224 6225 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6226 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6227 merely zeroed. 6228 6229 The user can set a value in the diagonal entry (or for the AIJ and 6230 row formats can optionally remove the main diagonal entry from the 6231 nonzero structure as well, by passing 0.0 as the final argument). 6232 6233 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6234 owns that are to be zeroed. This saves a global synchronization in the implementation. 6235 6236 Level: intermediate 6237 6238 Concepts: matrices^zeroing 6239 6240 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6241 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6242 @*/ 6243 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6244 { 6245 PetscErrorCode ierr; 6246 PetscInt numRows; 6247 const PetscInt *rows; 6248 6249 PetscFunctionBegin; 6250 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6251 PetscValidType(mat,1); 6252 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6253 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6254 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6255 MatCheckPreallocated(mat,1); 6256 6257 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6258 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6259 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6260 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6261 PetscFunctionReturn(0); 6262 } 6263 6264 /*@ 6265 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6266 of a set of rows and columns of a matrix; using local numbering of rows. 6267 6268 Collective on Mat 6269 6270 Input Parameters: 6271 + mat - the matrix 6272 . numRows - the number of rows to remove 6273 . rows - the global row indices 6274 . diag - value put in all diagonals of eliminated rows 6275 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6276 - b - optional vector of right hand side, that will be adjusted by provided solution 6277 6278 Notes: 6279 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6280 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6281 6282 The user can set a value in the diagonal entry (or for the AIJ and 6283 row formats can optionally remove the main diagonal entry from the 6284 nonzero structure as well, by passing 0.0 as the final argument). 6285 6286 Level: intermediate 6287 6288 Concepts: matrices^zeroing 6289 6290 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6291 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6292 @*/ 6293 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6294 { 6295 PetscErrorCode ierr; 6296 IS is, newis; 6297 const PetscInt *newRows; 6298 6299 PetscFunctionBegin; 6300 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6301 PetscValidType(mat,1); 6302 if (numRows) PetscValidIntPointer(rows,3); 6303 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6304 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6305 MatCheckPreallocated(mat,1); 6306 6307 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6308 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6309 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6310 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6311 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6312 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6313 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6314 ierr = ISDestroy(&is);CHKERRQ(ierr); 6315 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6316 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6317 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6318 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6319 } 6320 #endif 6321 PetscFunctionReturn(0); 6322 } 6323 6324 /*@ 6325 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6326 of a set of rows and columns of a matrix; using local numbering of rows. 6327 6328 Collective on Mat 6329 6330 Input Parameters: 6331 + mat - the matrix 6332 . is - index set of rows to remove 6333 . diag - value put in all diagonals of eliminated rows 6334 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6335 - b - optional vector of right hand side, that will be adjusted by provided solution 6336 6337 Notes: 6338 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6339 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6340 6341 The user can set a value in the diagonal entry (or for the AIJ and 6342 row formats can optionally remove the main diagonal entry from the 6343 nonzero structure as well, by passing 0.0 as the final argument). 6344 6345 Level: intermediate 6346 6347 Concepts: matrices^zeroing 6348 6349 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6350 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6351 @*/ 6352 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6353 { 6354 PetscErrorCode ierr; 6355 PetscInt numRows; 6356 const PetscInt *rows; 6357 6358 PetscFunctionBegin; 6359 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6360 PetscValidType(mat,1); 6361 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6362 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6363 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6364 MatCheckPreallocated(mat,1); 6365 6366 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6367 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6368 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6369 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6370 PetscFunctionReturn(0); 6371 } 6372 6373 /*@C 6374 MatGetSize - Returns the numbers of rows and columns in a matrix. 6375 6376 Not Collective 6377 6378 Input Parameter: 6379 . mat - the matrix 6380 6381 Output Parameters: 6382 + m - the number of global rows 6383 - n - the number of global columns 6384 6385 Note: both output parameters can be NULL on input. 6386 6387 Level: beginner 6388 6389 Concepts: matrices^size 6390 6391 .seealso: MatGetLocalSize() 6392 @*/ 6393 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6394 { 6395 PetscFunctionBegin; 6396 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6397 if (m) *m = mat->rmap->N; 6398 if (n) *n = mat->cmap->N; 6399 PetscFunctionReturn(0); 6400 } 6401 6402 /*@C 6403 MatGetLocalSize - Returns the number of rows and columns in a matrix 6404 stored locally. This information may be implementation dependent, so 6405 use with care. 6406 6407 Not Collective 6408 6409 Input Parameters: 6410 . mat - the matrix 6411 6412 Output Parameters: 6413 + m - the number of local rows 6414 - n - the number of local columns 6415 6416 Note: both output parameters can be NULL on input. 6417 6418 Level: beginner 6419 6420 Concepts: matrices^local size 6421 6422 .seealso: MatGetSize() 6423 @*/ 6424 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6425 { 6426 PetscFunctionBegin; 6427 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6428 if (m) PetscValidIntPointer(m,2); 6429 if (n) PetscValidIntPointer(n,3); 6430 if (m) *m = mat->rmap->n; 6431 if (n) *n = mat->cmap->n; 6432 PetscFunctionReturn(0); 6433 } 6434 6435 /*@C 6436 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6437 this processor. (The columns of the "diagonal block") 6438 6439 Not Collective, unless matrix has not been allocated, then collective on Mat 6440 6441 Input Parameters: 6442 . mat - the matrix 6443 6444 Output Parameters: 6445 + m - the global index of the first local column 6446 - n - one more than the global index of the last local column 6447 6448 Notes: 6449 both output parameters can be NULL on input. 6450 6451 Level: developer 6452 6453 Concepts: matrices^column ownership 6454 6455 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6456 6457 @*/ 6458 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6459 { 6460 PetscFunctionBegin; 6461 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6462 PetscValidType(mat,1); 6463 if (m) PetscValidIntPointer(m,2); 6464 if (n) PetscValidIntPointer(n,3); 6465 MatCheckPreallocated(mat,1); 6466 if (m) *m = mat->cmap->rstart; 6467 if (n) *n = mat->cmap->rend; 6468 PetscFunctionReturn(0); 6469 } 6470 6471 /*@C 6472 MatGetOwnershipRange - Returns the range of matrix rows owned by 6473 this processor, assuming that the matrix is laid out with the first 6474 n1 rows on the first processor, the next n2 rows on the second, etc. 6475 For certain parallel layouts this range may not be well defined. 6476 6477 Not Collective 6478 6479 Input Parameters: 6480 . mat - the matrix 6481 6482 Output Parameters: 6483 + m - the global index of the first local row 6484 - n - one more than the global index of the last local row 6485 6486 Note: Both output parameters can be NULL on input. 6487 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6488 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6489 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6490 6491 Level: beginner 6492 6493 Concepts: matrices^row ownership 6494 6495 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6496 6497 @*/ 6498 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6499 { 6500 PetscFunctionBegin; 6501 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6502 PetscValidType(mat,1); 6503 if (m) PetscValidIntPointer(m,2); 6504 if (n) PetscValidIntPointer(n,3); 6505 MatCheckPreallocated(mat,1); 6506 if (m) *m = mat->rmap->rstart; 6507 if (n) *n = mat->rmap->rend; 6508 PetscFunctionReturn(0); 6509 } 6510 6511 /*@C 6512 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6513 each process 6514 6515 Not Collective, unless matrix has not been allocated, then collective on Mat 6516 6517 Input Parameters: 6518 . mat - the matrix 6519 6520 Output Parameters: 6521 . ranges - start of each processors portion plus one more than the total length at the end 6522 6523 Level: beginner 6524 6525 Concepts: matrices^row ownership 6526 6527 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6528 6529 @*/ 6530 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6531 { 6532 PetscErrorCode ierr; 6533 6534 PetscFunctionBegin; 6535 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6536 PetscValidType(mat,1); 6537 MatCheckPreallocated(mat,1); 6538 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6539 PetscFunctionReturn(0); 6540 } 6541 6542 /*@C 6543 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6544 this processor. (The columns of the "diagonal blocks" for each process) 6545 6546 Not Collective, unless matrix has not been allocated, then collective on Mat 6547 6548 Input Parameters: 6549 . mat - the matrix 6550 6551 Output Parameters: 6552 . ranges - start of each processors portion plus one more then the total length at the end 6553 6554 Level: beginner 6555 6556 Concepts: matrices^column ownership 6557 6558 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6559 6560 @*/ 6561 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6562 { 6563 PetscErrorCode ierr; 6564 6565 PetscFunctionBegin; 6566 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6567 PetscValidType(mat,1); 6568 MatCheckPreallocated(mat,1); 6569 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6570 PetscFunctionReturn(0); 6571 } 6572 6573 /*@C 6574 MatGetOwnershipIS - Get row and column ownership as index sets 6575 6576 Not Collective 6577 6578 Input Arguments: 6579 . A - matrix of type Elemental 6580 6581 Output Arguments: 6582 + rows - rows in which this process owns elements 6583 . cols - columns in which this process owns elements 6584 6585 Level: intermediate 6586 6587 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6588 @*/ 6589 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6590 { 6591 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6592 6593 PetscFunctionBegin; 6594 MatCheckPreallocated(A,1); 6595 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6596 if (f) { 6597 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6598 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6599 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6600 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6601 } 6602 PetscFunctionReturn(0); 6603 } 6604 6605 /*@C 6606 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6607 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6608 to complete the factorization. 6609 6610 Collective on Mat 6611 6612 Input Parameters: 6613 + mat - the matrix 6614 . row - row permutation 6615 . column - column permutation 6616 - info - structure containing 6617 $ levels - number of levels of fill. 6618 $ expected fill - as ratio of original fill. 6619 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6620 missing diagonal entries) 6621 6622 Output Parameters: 6623 . fact - new matrix that has been symbolically factored 6624 6625 Notes: 6626 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6627 6628 Most users should employ the simplified KSP interface for linear solvers 6629 instead of working directly with matrix algebra routines such as this. 6630 See, e.g., KSPCreate(). 6631 6632 Level: developer 6633 6634 Concepts: matrices^symbolic LU factorization 6635 Concepts: matrices^factorization 6636 Concepts: LU^symbolic factorization 6637 6638 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6639 MatGetOrdering(), MatFactorInfo 6640 6641 Developer Note: fortran interface is not autogenerated as the f90 6642 interface defintion cannot be generated correctly [due to MatFactorInfo] 6643 6644 @*/ 6645 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6646 { 6647 PetscErrorCode ierr; 6648 6649 PetscFunctionBegin; 6650 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6651 PetscValidType(mat,1); 6652 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6653 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6654 PetscValidPointer(info,4); 6655 PetscValidPointer(fact,5); 6656 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6657 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6658 if (!(fact)->ops->ilufactorsymbolic) { 6659 MatSolverType spackage; 6660 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6661 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6662 } 6663 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6664 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6665 MatCheckPreallocated(mat,2); 6666 6667 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6668 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6669 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6670 PetscFunctionReturn(0); 6671 } 6672 6673 /*@C 6674 MatICCFactorSymbolic - Performs symbolic incomplete 6675 Cholesky factorization for a symmetric matrix. Use 6676 MatCholeskyFactorNumeric() to complete the factorization. 6677 6678 Collective on Mat 6679 6680 Input Parameters: 6681 + mat - the matrix 6682 . perm - row and column permutation 6683 - info - structure containing 6684 $ levels - number of levels of fill. 6685 $ expected fill - as ratio of original fill. 6686 6687 Output Parameter: 6688 . fact - the factored matrix 6689 6690 Notes: 6691 Most users should employ the KSP interface for linear solvers 6692 instead of working directly with matrix algebra routines such as this. 6693 See, e.g., KSPCreate(). 6694 6695 Level: developer 6696 6697 Concepts: matrices^symbolic incomplete Cholesky factorization 6698 Concepts: matrices^factorization 6699 Concepts: Cholsky^symbolic factorization 6700 6701 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6702 6703 Developer Note: fortran interface is not autogenerated as the f90 6704 interface defintion cannot be generated correctly [due to MatFactorInfo] 6705 6706 @*/ 6707 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6708 { 6709 PetscErrorCode ierr; 6710 6711 PetscFunctionBegin; 6712 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6713 PetscValidType(mat,1); 6714 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6715 PetscValidPointer(info,3); 6716 PetscValidPointer(fact,4); 6717 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6718 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6719 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6720 if (!(fact)->ops->iccfactorsymbolic) { 6721 MatSolverType spackage; 6722 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6723 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6724 } 6725 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6726 MatCheckPreallocated(mat,2); 6727 6728 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6729 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6730 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6731 PetscFunctionReturn(0); 6732 } 6733 6734 /*@C 6735 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6736 points to an array of valid matrices, they may be reused to store the new 6737 submatrices. 6738 6739 Collective on Mat 6740 6741 Input Parameters: 6742 + mat - the matrix 6743 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6744 . irow, icol - index sets of rows and columns to extract 6745 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6746 6747 Output Parameter: 6748 . submat - the array of submatrices 6749 6750 Notes: 6751 MatCreateSubMatrices() can extract ONLY sequential submatrices 6752 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6753 to extract a parallel submatrix. 6754 6755 Some matrix types place restrictions on the row and column 6756 indices, such as that they be sorted or that they be equal to each other. 6757 6758 The index sets may not have duplicate entries. 6759 6760 When extracting submatrices from a parallel matrix, each processor can 6761 form a different submatrix by setting the rows and columns of its 6762 individual index sets according to the local submatrix desired. 6763 6764 When finished using the submatrices, the user should destroy 6765 them with MatDestroySubMatrices(). 6766 6767 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6768 original matrix has not changed from that last call to MatCreateSubMatrices(). 6769 6770 This routine creates the matrices in submat; you should NOT create them before 6771 calling it. It also allocates the array of matrix pointers submat. 6772 6773 For BAIJ matrices the index sets must respect the block structure, that is if they 6774 request one row/column in a block, they must request all rows/columns that are in 6775 that block. For example, if the block size is 2 you cannot request just row 0 and 6776 column 0. 6777 6778 Fortran Note: 6779 The Fortran interface is slightly different from that given below; it 6780 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6781 6782 Level: advanced 6783 6784 Concepts: matrices^accessing submatrices 6785 Concepts: submatrices 6786 6787 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6788 @*/ 6789 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6790 { 6791 PetscErrorCode ierr; 6792 PetscInt i; 6793 PetscBool eq; 6794 6795 PetscFunctionBegin; 6796 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6797 PetscValidType(mat,1); 6798 if (n) { 6799 PetscValidPointer(irow,3); 6800 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6801 PetscValidPointer(icol,4); 6802 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6803 } 6804 PetscValidPointer(submat,6); 6805 if (n && scall == MAT_REUSE_MATRIX) { 6806 PetscValidPointer(*submat,6); 6807 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6808 } 6809 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6810 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6811 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6812 MatCheckPreallocated(mat,1); 6813 6814 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6815 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6816 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6817 for (i=0; i<n; i++) { 6818 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6819 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6820 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6821 if (eq) { 6822 if (mat->symmetric) { 6823 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6824 } else if (mat->hermitian) { 6825 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6826 } else if (mat->structurally_symmetric) { 6827 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6828 } 6829 } 6830 } 6831 } 6832 PetscFunctionReturn(0); 6833 } 6834 6835 /*@C 6836 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6837 6838 Collective on Mat 6839 6840 Input Parameters: 6841 + mat - the matrix 6842 . n - the number of submatrixes to be extracted 6843 . irow, icol - index sets of rows and columns to extract 6844 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6845 6846 Output Parameter: 6847 . submat - the array of submatrices 6848 6849 Level: advanced 6850 6851 Concepts: matrices^accessing submatrices 6852 Concepts: submatrices 6853 6854 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6855 @*/ 6856 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6857 { 6858 PetscErrorCode ierr; 6859 PetscInt i; 6860 PetscBool eq; 6861 6862 PetscFunctionBegin; 6863 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6864 PetscValidType(mat,1); 6865 if (n) { 6866 PetscValidPointer(irow,3); 6867 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6868 PetscValidPointer(icol,4); 6869 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6870 } 6871 PetscValidPointer(submat,6); 6872 if (n && scall == MAT_REUSE_MATRIX) { 6873 PetscValidPointer(*submat,6); 6874 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6875 } 6876 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6877 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6878 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6879 MatCheckPreallocated(mat,1); 6880 6881 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6882 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6883 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6884 for (i=0; i<n; i++) { 6885 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6886 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6887 if (eq) { 6888 if (mat->symmetric) { 6889 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6890 } else if (mat->hermitian) { 6891 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6892 } else if (mat->structurally_symmetric) { 6893 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6894 } 6895 } 6896 } 6897 } 6898 PetscFunctionReturn(0); 6899 } 6900 6901 /*@C 6902 MatDestroyMatrices - Destroys an array of matrices. 6903 6904 Collective on Mat 6905 6906 Input Parameters: 6907 + n - the number of local matrices 6908 - mat - the matrices (note that this is a pointer to the array of matrices) 6909 6910 Level: advanced 6911 6912 Notes: 6913 Frees not only the matrices, but also the array that contains the matrices 6914 In Fortran will not free the array. 6915 6916 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6917 @*/ 6918 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6919 { 6920 PetscErrorCode ierr; 6921 PetscInt i; 6922 6923 PetscFunctionBegin; 6924 if (!*mat) PetscFunctionReturn(0); 6925 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6926 PetscValidPointer(mat,2); 6927 6928 for (i=0; i<n; i++) { 6929 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6930 } 6931 6932 /* memory is allocated even if n = 0 */ 6933 ierr = PetscFree(*mat);CHKERRQ(ierr); 6934 PetscFunctionReturn(0); 6935 } 6936 6937 /*@C 6938 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6939 6940 Collective on Mat 6941 6942 Input Parameters: 6943 + n - the number of local matrices 6944 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6945 sequence of MatCreateSubMatrices()) 6946 6947 Level: advanced 6948 6949 Notes: 6950 Frees not only the matrices, but also the array that contains the matrices 6951 In Fortran will not free the array. 6952 6953 .seealso: MatCreateSubMatrices() 6954 @*/ 6955 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6956 { 6957 PetscErrorCode ierr; 6958 Mat mat0; 6959 6960 PetscFunctionBegin; 6961 if (!*mat) PetscFunctionReturn(0); 6962 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6963 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6964 PetscValidPointer(mat,2); 6965 6966 mat0 = (*mat)[0]; 6967 if (mat0 && mat0->ops->destroysubmatrices) { 6968 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 6969 } else { 6970 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 6971 } 6972 PetscFunctionReturn(0); 6973 } 6974 6975 /*@C 6976 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6977 6978 Collective on Mat 6979 6980 Input Parameters: 6981 . mat - the matrix 6982 6983 Output Parameter: 6984 . matstruct - the sequential matrix with the nonzero structure of mat 6985 6986 Level: intermediate 6987 6988 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6989 @*/ 6990 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6991 { 6992 PetscErrorCode ierr; 6993 6994 PetscFunctionBegin; 6995 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6996 PetscValidPointer(matstruct,2); 6997 6998 PetscValidType(mat,1); 6999 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7000 MatCheckPreallocated(mat,1); 7001 7002 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 7003 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7004 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 7005 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7006 PetscFunctionReturn(0); 7007 } 7008 7009 /*@C 7010 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7011 7012 Collective on Mat 7013 7014 Input Parameters: 7015 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7016 sequence of MatGetSequentialNonzeroStructure()) 7017 7018 Level: advanced 7019 7020 Notes: 7021 Frees not only the matrices, but also the array that contains the matrices 7022 7023 .seealso: MatGetSeqNonzeroStructure() 7024 @*/ 7025 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7026 { 7027 PetscErrorCode ierr; 7028 7029 PetscFunctionBegin; 7030 PetscValidPointer(mat,1); 7031 ierr = MatDestroy(mat);CHKERRQ(ierr); 7032 PetscFunctionReturn(0); 7033 } 7034 7035 /*@ 7036 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7037 replaces the index sets by larger ones that represent submatrices with 7038 additional overlap. 7039 7040 Collective on Mat 7041 7042 Input Parameters: 7043 + mat - the matrix 7044 . n - the number of index sets 7045 . is - the array of index sets (these index sets will changed during the call) 7046 - ov - the additional overlap requested 7047 7048 Options Database: 7049 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7050 7051 Level: developer 7052 7053 Concepts: overlap 7054 Concepts: ASM^computing overlap 7055 7056 .seealso: MatCreateSubMatrices() 7057 @*/ 7058 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7059 { 7060 PetscErrorCode ierr; 7061 7062 PetscFunctionBegin; 7063 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7064 PetscValidType(mat,1); 7065 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7066 if (n) { 7067 PetscValidPointer(is,3); 7068 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7069 } 7070 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7071 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7072 MatCheckPreallocated(mat,1); 7073 7074 if (!ov) PetscFunctionReturn(0); 7075 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7076 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7077 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7078 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7079 PetscFunctionReturn(0); 7080 } 7081 7082 7083 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7084 7085 /*@ 7086 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7087 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7088 additional overlap. 7089 7090 Collective on Mat 7091 7092 Input Parameters: 7093 + mat - the matrix 7094 . n - the number of index sets 7095 . is - the array of index sets (these index sets will changed during the call) 7096 - ov - the additional overlap requested 7097 7098 Options Database: 7099 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7100 7101 Level: developer 7102 7103 Concepts: overlap 7104 Concepts: ASM^computing overlap 7105 7106 .seealso: MatCreateSubMatrices() 7107 @*/ 7108 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7109 { 7110 PetscInt i; 7111 PetscErrorCode ierr; 7112 7113 PetscFunctionBegin; 7114 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7115 PetscValidType(mat,1); 7116 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7117 if (n) { 7118 PetscValidPointer(is,3); 7119 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7120 } 7121 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7122 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7123 MatCheckPreallocated(mat,1); 7124 if (!ov) PetscFunctionReturn(0); 7125 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7126 for(i=0; i<n; i++){ 7127 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7128 } 7129 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7130 PetscFunctionReturn(0); 7131 } 7132 7133 7134 7135 7136 /*@ 7137 MatGetBlockSize - Returns the matrix block size. 7138 7139 Not Collective 7140 7141 Input Parameter: 7142 . mat - the matrix 7143 7144 Output Parameter: 7145 . bs - block size 7146 7147 Notes: 7148 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7149 7150 If the block size has not been set yet this routine returns 1. 7151 7152 Level: intermediate 7153 7154 Concepts: matrices^block size 7155 7156 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7157 @*/ 7158 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7159 { 7160 PetscFunctionBegin; 7161 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7162 PetscValidIntPointer(bs,2); 7163 *bs = PetscAbs(mat->rmap->bs); 7164 PetscFunctionReturn(0); 7165 } 7166 7167 /*@ 7168 MatGetBlockSizes - Returns the matrix block row and column sizes. 7169 7170 Not Collective 7171 7172 Input Parameter: 7173 . mat - the matrix 7174 7175 Output Parameter: 7176 . rbs - row block size 7177 . cbs - column block size 7178 7179 Notes: 7180 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7181 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7182 7183 If a block size has not been set yet this routine returns 1. 7184 7185 Level: intermediate 7186 7187 Concepts: matrices^block size 7188 7189 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7190 @*/ 7191 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7192 { 7193 PetscFunctionBegin; 7194 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7195 if (rbs) PetscValidIntPointer(rbs,2); 7196 if (cbs) PetscValidIntPointer(cbs,3); 7197 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7198 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7199 PetscFunctionReturn(0); 7200 } 7201 7202 /*@ 7203 MatSetBlockSize - Sets the matrix block size. 7204 7205 Logically Collective on Mat 7206 7207 Input Parameters: 7208 + mat - the matrix 7209 - bs - block size 7210 7211 Notes: 7212 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7213 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7214 7215 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7216 is compatible with the matrix local sizes. 7217 7218 Level: intermediate 7219 7220 Concepts: matrices^block size 7221 7222 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7223 @*/ 7224 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7225 { 7226 PetscErrorCode ierr; 7227 7228 PetscFunctionBegin; 7229 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7230 PetscValidLogicalCollectiveInt(mat,bs,2); 7231 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7232 PetscFunctionReturn(0); 7233 } 7234 7235 /*@ 7236 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7237 7238 Logically Collective on Mat 7239 7240 Input Parameters: 7241 + mat - the matrix 7242 . nblocks - the number of blocks on this process 7243 - bsizes - the block sizes 7244 7245 Notes: 7246 Currently used by PCVPBJACOBI for SeqAIJ matrices 7247 7248 Level: intermediate 7249 7250 Concepts: matrices^block size 7251 7252 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7253 @*/ 7254 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7255 { 7256 PetscErrorCode ierr; 7257 PetscInt i,ncnt = 0, nlocal; 7258 7259 PetscFunctionBegin; 7260 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7261 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7262 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7263 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7264 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); 7265 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7266 mat->nblocks = nblocks; 7267 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7268 ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr); 7269 PetscFunctionReturn(0); 7270 } 7271 7272 /*@C 7273 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7274 7275 Logically Collective on Mat 7276 7277 Input Parameters: 7278 . mat - the matrix 7279 7280 Output Parameters: 7281 + nblocks - the number of blocks on this process 7282 - bsizes - the block sizes 7283 7284 Notes: Currently not supported from Fortran 7285 7286 Level: intermediate 7287 7288 Concepts: matrices^block size 7289 7290 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7291 @*/ 7292 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7293 { 7294 PetscFunctionBegin; 7295 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7296 *nblocks = mat->nblocks; 7297 *bsizes = mat->bsizes; 7298 PetscFunctionReturn(0); 7299 } 7300 7301 /*@ 7302 MatSetBlockSizes - Sets the matrix block row and column sizes. 7303 7304 Logically Collective on Mat 7305 7306 Input Parameters: 7307 + mat - the matrix 7308 - rbs - row block size 7309 - cbs - column block size 7310 7311 Notes: 7312 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7313 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7314 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7315 7316 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7317 are compatible with the matrix local sizes. 7318 7319 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7320 7321 Level: intermediate 7322 7323 Concepts: matrices^block size 7324 7325 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7326 @*/ 7327 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7328 { 7329 PetscErrorCode ierr; 7330 7331 PetscFunctionBegin; 7332 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7333 PetscValidLogicalCollectiveInt(mat,rbs,2); 7334 PetscValidLogicalCollectiveInt(mat,cbs,3); 7335 if (mat->ops->setblocksizes) { 7336 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7337 } 7338 if (mat->rmap->refcnt) { 7339 ISLocalToGlobalMapping l2g = NULL; 7340 PetscLayout nmap = NULL; 7341 7342 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7343 if (mat->rmap->mapping) { 7344 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7345 } 7346 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7347 mat->rmap = nmap; 7348 mat->rmap->mapping = l2g; 7349 } 7350 if (mat->cmap->refcnt) { 7351 ISLocalToGlobalMapping l2g = NULL; 7352 PetscLayout nmap = NULL; 7353 7354 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7355 if (mat->cmap->mapping) { 7356 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7357 } 7358 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7359 mat->cmap = nmap; 7360 mat->cmap->mapping = l2g; 7361 } 7362 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7363 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7364 PetscFunctionReturn(0); 7365 } 7366 7367 /*@ 7368 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7369 7370 Logically Collective on Mat 7371 7372 Input Parameters: 7373 + mat - the matrix 7374 . fromRow - matrix from which to copy row block size 7375 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7376 7377 Level: developer 7378 7379 Concepts: matrices^block size 7380 7381 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7382 @*/ 7383 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7384 { 7385 PetscErrorCode ierr; 7386 7387 PetscFunctionBegin; 7388 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7389 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7390 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7391 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7392 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7393 PetscFunctionReturn(0); 7394 } 7395 7396 /*@ 7397 MatResidual - Default routine to calculate the residual. 7398 7399 Collective on Mat and Vec 7400 7401 Input Parameters: 7402 + mat - the matrix 7403 . b - the right-hand-side 7404 - x - the approximate solution 7405 7406 Output Parameter: 7407 . r - location to store the residual 7408 7409 Level: developer 7410 7411 .keywords: MG, default, multigrid, residual 7412 7413 .seealso: PCMGSetResidual() 7414 @*/ 7415 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7416 { 7417 PetscErrorCode ierr; 7418 7419 PetscFunctionBegin; 7420 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7421 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7422 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7423 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7424 PetscValidType(mat,1); 7425 MatCheckPreallocated(mat,1); 7426 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7427 if (!mat->ops->residual) { 7428 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7429 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7430 } else { 7431 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7432 } 7433 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7434 PetscFunctionReturn(0); 7435 } 7436 7437 /*@C 7438 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7439 7440 Collective on Mat 7441 7442 Input Parameters: 7443 + mat - the matrix 7444 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7445 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7446 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7447 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7448 always used. 7449 7450 Output Parameters: 7451 + n - number of rows in the (possibly compressed) matrix 7452 . ia - the row pointers [of length n+1] 7453 . ja - the column indices 7454 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7455 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7456 7457 Level: developer 7458 7459 Notes: 7460 You CANNOT change any of the ia[] or ja[] values. 7461 7462 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7463 7464 Fortran Notes: 7465 In Fortran use 7466 $ 7467 $ PetscInt ia(1), ja(1) 7468 $ PetscOffset iia, jja 7469 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7470 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7471 7472 or 7473 $ 7474 $ PetscInt, pointer :: ia(:),ja(:) 7475 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7476 $ ! Access the ith and jth entries via ia(i) and ja(j) 7477 7478 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7479 @*/ 7480 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7481 { 7482 PetscErrorCode ierr; 7483 7484 PetscFunctionBegin; 7485 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7486 PetscValidType(mat,1); 7487 PetscValidIntPointer(n,5); 7488 if (ia) PetscValidIntPointer(ia,6); 7489 if (ja) PetscValidIntPointer(ja,7); 7490 PetscValidIntPointer(done,8); 7491 MatCheckPreallocated(mat,1); 7492 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7493 else { 7494 *done = PETSC_TRUE; 7495 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7496 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7497 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7498 } 7499 PetscFunctionReturn(0); 7500 } 7501 7502 /*@C 7503 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7504 7505 Collective on Mat 7506 7507 Input Parameters: 7508 + mat - the matrix 7509 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7510 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7511 symmetrized 7512 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7513 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7514 always used. 7515 . n - number of columns in the (possibly compressed) matrix 7516 . ia - the column pointers 7517 - ja - the row indices 7518 7519 Output Parameters: 7520 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7521 7522 Note: 7523 This routine zeros out n, ia, and ja. This is to prevent accidental 7524 us of the array after it has been restored. If you pass NULL, it will 7525 not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid. 7526 7527 Level: developer 7528 7529 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7530 @*/ 7531 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7532 { 7533 PetscErrorCode ierr; 7534 7535 PetscFunctionBegin; 7536 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7537 PetscValidType(mat,1); 7538 PetscValidIntPointer(n,4); 7539 if (ia) PetscValidIntPointer(ia,5); 7540 if (ja) PetscValidIntPointer(ja,6); 7541 PetscValidIntPointer(done,7); 7542 MatCheckPreallocated(mat,1); 7543 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7544 else { 7545 *done = PETSC_TRUE; 7546 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7547 } 7548 PetscFunctionReturn(0); 7549 } 7550 7551 /*@C 7552 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7553 MatGetRowIJ(). 7554 7555 Collective on Mat 7556 7557 Input Parameters: 7558 + mat - the matrix 7559 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7560 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7561 symmetrized 7562 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7563 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7564 always used. 7565 . n - size of (possibly compressed) matrix 7566 . ia - the row pointers 7567 - ja - the column indices 7568 7569 Output Parameters: 7570 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7571 7572 Note: 7573 This routine zeros out n, ia, and ja. This is to prevent accidental 7574 us of the array after it has been restored. If you pass NULL, it will 7575 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7576 7577 Level: developer 7578 7579 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7580 @*/ 7581 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7582 { 7583 PetscErrorCode ierr; 7584 7585 PetscFunctionBegin; 7586 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7587 PetscValidType(mat,1); 7588 if (ia) PetscValidIntPointer(ia,6); 7589 if (ja) PetscValidIntPointer(ja,7); 7590 PetscValidIntPointer(done,8); 7591 MatCheckPreallocated(mat,1); 7592 7593 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7594 else { 7595 *done = PETSC_TRUE; 7596 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7597 if (n) *n = 0; 7598 if (ia) *ia = NULL; 7599 if (ja) *ja = NULL; 7600 } 7601 PetscFunctionReturn(0); 7602 } 7603 7604 /*@C 7605 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7606 MatGetColumnIJ(). 7607 7608 Collective on Mat 7609 7610 Input Parameters: 7611 + mat - the matrix 7612 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7613 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7614 symmetrized 7615 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7616 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7617 always used. 7618 7619 Output Parameters: 7620 + n - size of (possibly compressed) matrix 7621 . ia - the column pointers 7622 . ja - the row indices 7623 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7624 7625 Level: developer 7626 7627 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7628 @*/ 7629 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7630 { 7631 PetscErrorCode ierr; 7632 7633 PetscFunctionBegin; 7634 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7635 PetscValidType(mat,1); 7636 if (ia) PetscValidIntPointer(ia,5); 7637 if (ja) PetscValidIntPointer(ja,6); 7638 PetscValidIntPointer(done,7); 7639 MatCheckPreallocated(mat,1); 7640 7641 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7642 else { 7643 *done = PETSC_TRUE; 7644 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7645 if (n) *n = 0; 7646 if (ia) *ia = NULL; 7647 if (ja) *ja = NULL; 7648 } 7649 PetscFunctionReturn(0); 7650 } 7651 7652 /*@C 7653 MatColoringPatch -Used inside matrix coloring routines that 7654 use MatGetRowIJ() and/or MatGetColumnIJ(). 7655 7656 Collective on Mat 7657 7658 Input Parameters: 7659 + mat - the matrix 7660 . ncolors - max color value 7661 . n - number of entries in colorarray 7662 - colorarray - array indicating color for each column 7663 7664 Output Parameters: 7665 . iscoloring - coloring generated using colorarray information 7666 7667 Level: developer 7668 7669 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7670 7671 @*/ 7672 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7673 { 7674 PetscErrorCode ierr; 7675 7676 PetscFunctionBegin; 7677 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7678 PetscValidType(mat,1); 7679 PetscValidIntPointer(colorarray,4); 7680 PetscValidPointer(iscoloring,5); 7681 MatCheckPreallocated(mat,1); 7682 7683 if (!mat->ops->coloringpatch) { 7684 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7685 } else { 7686 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7687 } 7688 PetscFunctionReturn(0); 7689 } 7690 7691 7692 /*@ 7693 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7694 7695 Logically Collective on Mat 7696 7697 Input Parameter: 7698 . mat - the factored matrix to be reset 7699 7700 Notes: 7701 This routine should be used only with factored matrices formed by in-place 7702 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7703 format). This option can save memory, for example, when solving nonlinear 7704 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7705 ILU(0) preconditioner. 7706 7707 Note that one can specify in-place ILU(0) factorization by calling 7708 .vb 7709 PCType(pc,PCILU); 7710 PCFactorSeUseInPlace(pc); 7711 .ve 7712 or by using the options -pc_type ilu -pc_factor_in_place 7713 7714 In-place factorization ILU(0) can also be used as a local 7715 solver for the blocks within the block Jacobi or additive Schwarz 7716 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7717 for details on setting local solver options. 7718 7719 Most users should employ the simplified KSP interface for linear solvers 7720 instead of working directly with matrix algebra routines such as this. 7721 See, e.g., KSPCreate(). 7722 7723 Level: developer 7724 7725 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7726 7727 Concepts: matrices^unfactored 7728 7729 @*/ 7730 PetscErrorCode MatSetUnfactored(Mat mat) 7731 { 7732 PetscErrorCode ierr; 7733 7734 PetscFunctionBegin; 7735 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7736 PetscValidType(mat,1); 7737 MatCheckPreallocated(mat,1); 7738 mat->factortype = MAT_FACTOR_NONE; 7739 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7740 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7741 PetscFunctionReturn(0); 7742 } 7743 7744 /*MC 7745 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7746 7747 Synopsis: 7748 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7749 7750 Not collective 7751 7752 Input Parameter: 7753 . x - matrix 7754 7755 Output Parameters: 7756 + xx_v - the Fortran90 pointer to the array 7757 - ierr - error code 7758 7759 Example of Usage: 7760 .vb 7761 PetscScalar, pointer xx_v(:,:) 7762 .... 7763 call MatDenseGetArrayF90(x,xx_v,ierr) 7764 a = xx_v(3) 7765 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7766 .ve 7767 7768 Level: advanced 7769 7770 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7771 7772 Concepts: matrices^accessing array 7773 7774 M*/ 7775 7776 /*MC 7777 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7778 accessed with MatDenseGetArrayF90(). 7779 7780 Synopsis: 7781 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7782 7783 Not collective 7784 7785 Input Parameters: 7786 + x - matrix 7787 - xx_v - the Fortran90 pointer to the array 7788 7789 Output Parameter: 7790 . ierr - error code 7791 7792 Example of Usage: 7793 .vb 7794 PetscScalar, pointer xx_v(:,:) 7795 .... 7796 call MatDenseGetArrayF90(x,xx_v,ierr) 7797 a = xx_v(3) 7798 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7799 .ve 7800 7801 Level: advanced 7802 7803 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7804 7805 M*/ 7806 7807 7808 /*MC 7809 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7810 7811 Synopsis: 7812 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7813 7814 Not collective 7815 7816 Input Parameter: 7817 . x - matrix 7818 7819 Output Parameters: 7820 + xx_v - the Fortran90 pointer to the array 7821 - ierr - error code 7822 7823 Example of Usage: 7824 .vb 7825 PetscScalar, pointer xx_v(:) 7826 .... 7827 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7828 a = xx_v(3) 7829 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7830 .ve 7831 7832 Level: advanced 7833 7834 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7835 7836 Concepts: matrices^accessing array 7837 7838 M*/ 7839 7840 /*MC 7841 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7842 accessed with MatSeqAIJGetArrayF90(). 7843 7844 Synopsis: 7845 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7846 7847 Not collective 7848 7849 Input Parameters: 7850 + x - matrix 7851 - xx_v - the Fortran90 pointer to the array 7852 7853 Output Parameter: 7854 . ierr - error code 7855 7856 Example of Usage: 7857 .vb 7858 PetscScalar, pointer xx_v(:) 7859 .... 7860 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7861 a = xx_v(3) 7862 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7863 .ve 7864 7865 Level: advanced 7866 7867 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7868 7869 M*/ 7870 7871 7872 /*@ 7873 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7874 as the original matrix. 7875 7876 Collective on Mat 7877 7878 Input Parameters: 7879 + mat - the original matrix 7880 . isrow - parallel IS containing the rows this processor should obtain 7881 . 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. 7882 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7883 7884 Output Parameter: 7885 . newmat - the new submatrix, of the same type as the old 7886 7887 Level: advanced 7888 7889 Notes: 7890 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7891 7892 Some matrix types place restrictions on the row and column indices, such 7893 as that they be sorted or that they be equal to each other. 7894 7895 The index sets may not have duplicate entries. 7896 7897 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7898 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7899 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7900 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7901 you are finished using it. 7902 7903 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7904 the input matrix. 7905 7906 If iscol is NULL then all columns are obtained (not supported in Fortran). 7907 7908 Example usage: 7909 Consider the following 8x8 matrix with 34 non-zero values, that is 7910 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7911 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7912 as follows: 7913 7914 .vb 7915 1 2 0 | 0 3 0 | 0 4 7916 Proc0 0 5 6 | 7 0 0 | 8 0 7917 9 0 10 | 11 0 0 | 12 0 7918 ------------------------------------- 7919 13 0 14 | 15 16 17 | 0 0 7920 Proc1 0 18 0 | 19 20 21 | 0 0 7921 0 0 0 | 22 23 0 | 24 0 7922 ------------------------------------- 7923 Proc2 25 26 27 | 0 0 28 | 29 0 7924 30 0 0 | 31 32 33 | 0 34 7925 .ve 7926 7927 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7928 7929 .vb 7930 2 0 | 0 3 0 | 0 7931 Proc0 5 6 | 7 0 0 | 8 7932 ------------------------------- 7933 Proc1 18 0 | 19 20 21 | 0 7934 ------------------------------- 7935 Proc2 26 27 | 0 0 28 | 29 7936 0 0 | 31 32 33 | 0 7937 .ve 7938 7939 7940 Concepts: matrices^submatrices 7941 7942 .seealso: MatCreateSubMatrices() 7943 @*/ 7944 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7945 { 7946 PetscErrorCode ierr; 7947 PetscMPIInt size; 7948 Mat *local; 7949 IS iscoltmp; 7950 7951 PetscFunctionBegin; 7952 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7953 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7954 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7955 PetscValidPointer(newmat,5); 7956 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7957 PetscValidType(mat,1); 7958 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7959 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7960 7961 MatCheckPreallocated(mat,1); 7962 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7963 7964 if (!iscol || isrow == iscol) { 7965 PetscBool stride; 7966 PetscMPIInt grabentirematrix = 0,grab; 7967 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7968 if (stride) { 7969 PetscInt first,step,n,rstart,rend; 7970 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7971 if (step == 1) { 7972 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7973 if (rstart == first) { 7974 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7975 if (n == rend-rstart) { 7976 grabentirematrix = 1; 7977 } 7978 } 7979 } 7980 } 7981 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7982 if (grab) { 7983 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7984 if (cll == MAT_INITIAL_MATRIX) { 7985 *newmat = mat; 7986 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7987 } 7988 PetscFunctionReturn(0); 7989 } 7990 } 7991 7992 if (!iscol) { 7993 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7994 } else { 7995 iscoltmp = iscol; 7996 } 7997 7998 /* if original matrix is on just one processor then use submatrix generated */ 7999 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8000 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 8001 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8002 PetscFunctionReturn(0); 8003 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8004 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8005 *newmat = *local; 8006 ierr = PetscFree(local);CHKERRQ(ierr); 8007 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8008 PetscFunctionReturn(0); 8009 } else if (!mat->ops->createsubmatrix) { 8010 /* Create a new matrix type that implements the operation using the full matrix */ 8011 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8012 switch (cll) { 8013 case MAT_INITIAL_MATRIX: 8014 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8015 break; 8016 case MAT_REUSE_MATRIX: 8017 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8018 break; 8019 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8020 } 8021 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8022 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8023 PetscFunctionReturn(0); 8024 } 8025 8026 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8027 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8028 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8029 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8030 8031 /* Propagate symmetry information for diagonal blocks */ 8032 if (isrow == iscoltmp) { 8033 if (mat->symmetric_set && mat->symmetric) { 8034 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8035 } 8036 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 8037 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8038 } 8039 if (mat->hermitian_set && mat->hermitian) { 8040 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 8041 } 8042 if (mat->spd_set && mat->spd) { 8043 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 8044 } 8045 } 8046 8047 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8048 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8049 PetscFunctionReturn(0); 8050 } 8051 8052 /*@ 8053 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8054 used during the assembly process to store values that belong to 8055 other processors. 8056 8057 Not Collective 8058 8059 Input Parameters: 8060 + mat - the matrix 8061 . size - the initial size of the stash. 8062 - bsize - the initial size of the block-stash(if used). 8063 8064 Options Database Keys: 8065 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8066 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8067 8068 Level: intermediate 8069 8070 Notes: 8071 The block-stash is used for values set with MatSetValuesBlocked() while 8072 the stash is used for values set with MatSetValues() 8073 8074 Run with the option -info and look for output of the form 8075 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8076 to determine the appropriate value, MM, to use for size and 8077 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8078 to determine the value, BMM to use for bsize 8079 8080 Concepts: stash^setting matrix size 8081 Concepts: matrices^stash 8082 8083 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8084 8085 @*/ 8086 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8087 { 8088 PetscErrorCode ierr; 8089 8090 PetscFunctionBegin; 8091 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8092 PetscValidType(mat,1); 8093 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8094 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8095 PetscFunctionReturn(0); 8096 } 8097 8098 /*@ 8099 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8100 the matrix 8101 8102 Neighbor-wise Collective on Mat 8103 8104 Input Parameters: 8105 + mat - the matrix 8106 . x,y - the vectors 8107 - w - where the result is stored 8108 8109 Level: intermediate 8110 8111 Notes: 8112 w may be the same vector as y. 8113 8114 This allows one to use either the restriction or interpolation (its transpose) 8115 matrix to do the interpolation 8116 8117 Concepts: interpolation 8118 8119 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8120 8121 @*/ 8122 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8123 { 8124 PetscErrorCode ierr; 8125 PetscInt M,N,Ny; 8126 8127 PetscFunctionBegin; 8128 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8129 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8130 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8131 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8132 PetscValidType(A,1); 8133 MatCheckPreallocated(A,1); 8134 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8135 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8136 if (M == Ny) { 8137 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8138 } else { 8139 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8140 } 8141 PetscFunctionReturn(0); 8142 } 8143 8144 /*@ 8145 MatInterpolate - y = A*x or A'*x depending on the shape of 8146 the matrix 8147 8148 Neighbor-wise Collective on Mat 8149 8150 Input Parameters: 8151 + mat - the matrix 8152 - x,y - the vectors 8153 8154 Level: intermediate 8155 8156 Notes: 8157 This allows one to use either the restriction or interpolation (its transpose) 8158 matrix to do the interpolation 8159 8160 Concepts: matrices^interpolation 8161 8162 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8163 8164 @*/ 8165 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8166 { 8167 PetscErrorCode ierr; 8168 PetscInt M,N,Ny; 8169 8170 PetscFunctionBegin; 8171 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8172 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8173 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8174 PetscValidType(A,1); 8175 MatCheckPreallocated(A,1); 8176 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8177 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8178 if (M == Ny) { 8179 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8180 } else { 8181 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8182 } 8183 PetscFunctionReturn(0); 8184 } 8185 8186 /*@ 8187 MatRestrict - y = A*x or A'*x 8188 8189 Neighbor-wise Collective on Mat 8190 8191 Input Parameters: 8192 + mat - the matrix 8193 - x,y - the vectors 8194 8195 Level: intermediate 8196 8197 Notes: 8198 This allows one to use either the restriction or interpolation (its transpose) 8199 matrix to do the restriction 8200 8201 Concepts: matrices^restriction 8202 8203 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8204 8205 @*/ 8206 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8207 { 8208 PetscErrorCode ierr; 8209 PetscInt M,N,Ny; 8210 8211 PetscFunctionBegin; 8212 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8213 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8214 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8215 PetscValidType(A,1); 8216 MatCheckPreallocated(A,1); 8217 8218 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8219 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8220 if (M == Ny) { 8221 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8222 } else { 8223 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8224 } 8225 PetscFunctionReturn(0); 8226 } 8227 8228 /*@ 8229 MatGetNullSpace - retrieves the null space of a matrix. 8230 8231 Logically Collective on Mat and MatNullSpace 8232 8233 Input Parameters: 8234 + mat - the matrix 8235 - nullsp - the null space object 8236 8237 Level: developer 8238 8239 Concepts: null space^attaching to matrix 8240 8241 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8242 @*/ 8243 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8244 { 8245 PetscFunctionBegin; 8246 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8247 PetscValidPointer(nullsp,2); 8248 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8249 PetscFunctionReturn(0); 8250 } 8251 8252 /*@ 8253 MatSetNullSpace - attaches a null space to a matrix. 8254 8255 Logically Collective on Mat and MatNullSpace 8256 8257 Input Parameters: 8258 + mat - the matrix 8259 - nullsp - the null space object 8260 8261 Level: advanced 8262 8263 Notes: 8264 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8265 8266 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8267 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8268 8269 You can remove the null space by calling this routine with an nullsp of NULL 8270 8271 8272 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8273 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). 8274 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 8275 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 8276 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). 8277 8278 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8279 8280 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 8281 routine also automatically calls MatSetTransposeNullSpace(). 8282 8283 Concepts: null space^attaching to matrix 8284 8285 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8286 @*/ 8287 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8288 { 8289 PetscErrorCode ierr; 8290 8291 PetscFunctionBegin; 8292 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8293 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8294 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8295 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8296 mat->nullsp = nullsp; 8297 if (mat->symmetric_set && mat->symmetric) { 8298 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8299 } 8300 PetscFunctionReturn(0); 8301 } 8302 8303 /*@ 8304 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8305 8306 Logically Collective on Mat and MatNullSpace 8307 8308 Input Parameters: 8309 + mat - the matrix 8310 - nullsp - the null space object 8311 8312 Level: developer 8313 8314 Concepts: null space^attaching to matrix 8315 8316 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8317 @*/ 8318 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8319 { 8320 PetscFunctionBegin; 8321 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8322 PetscValidType(mat,1); 8323 PetscValidPointer(nullsp,2); 8324 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8325 PetscFunctionReturn(0); 8326 } 8327 8328 /*@ 8329 MatSetTransposeNullSpace - attaches a null space to a matrix. 8330 8331 Logically Collective on Mat and MatNullSpace 8332 8333 Input Parameters: 8334 + mat - the matrix 8335 - nullsp - the null space object 8336 8337 Level: advanced 8338 8339 Notes: 8340 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. 8341 You must also call MatSetNullSpace() 8342 8343 8344 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8345 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). 8346 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 8347 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 8348 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). 8349 8350 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8351 8352 Concepts: null space^attaching to matrix 8353 8354 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8355 @*/ 8356 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8357 { 8358 PetscErrorCode ierr; 8359 8360 PetscFunctionBegin; 8361 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8362 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8363 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8364 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8365 mat->transnullsp = nullsp; 8366 PetscFunctionReturn(0); 8367 } 8368 8369 /*@ 8370 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8371 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8372 8373 Logically Collective on Mat and MatNullSpace 8374 8375 Input Parameters: 8376 + mat - the matrix 8377 - nullsp - the null space object 8378 8379 Level: advanced 8380 8381 Notes: 8382 Overwrites any previous near null space that may have been attached 8383 8384 You can remove the null space by calling this routine with an nullsp of NULL 8385 8386 Concepts: null space^attaching to matrix 8387 8388 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8389 @*/ 8390 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8391 { 8392 PetscErrorCode ierr; 8393 8394 PetscFunctionBegin; 8395 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8396 PetscValidType(mat,1); 8397 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8398 MatCheckPreallocated(mat,1); 8399 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8400 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8401 mat->nearnullsp = nullsp; 8402 PetscFunctionReturn(0); 8403 } 8404 8405 /*@ 8406 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8407 8408 Not Collective 8409 8410 Input Parameters: 8411 . mat - the matrix 8412 8413 Output Parameters: 8414 . nullsp - the null space object, NULL if not set 8415 8416 Level: developer 8417 8418 Concepts: null space^attaching to matrix 8419 8420 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8421 @*/ 8422 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8423 { 8424 PetscFunctionBegin; 8425 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8426 PetscValidType(mat,1); 8427 PetscValidPointer(nullsp,2); 8428 MatCheckPreallocated(mat,1); 8429 *nullsp = mat->nearnullsp; 8430 PetscFunctionReturn(0); 8431 } 8432 8433 /*@C 8434 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8435 8436 Collective on Mat 8437 8438 Input Parameters: 8439 + mat - the matrix 8440 . row - row/column permutation 8441 . fill - expected fill factor >= 1.0 8442 - level - level of fill, for ICC(k) 8443 8444 Notes: 8445 Probably really in-place only when level of fill is zero, otherwise allocates 8446 new space to store factored matrix and deletes previous memory. 8447 8448 Most users should employ the simplified KSP interface for linear solvers 8449 instead of working directly with matrix algebra routines such as this. 8450 See, e.g., KSPCreate(). 8451 8452 Level: developer 8453 8454 Concepts: matrices^incomplete Cholesky factorization 8455 Concepts: Cholesky factorization 8456 8457 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8458 8459 Developer Note: fortran interface is not autogenerated as the f90 8460 interface defintion cannot be generated correctly [due to MatFactorInfo] 8461 8462 @*/ 8463 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8464 { 8465 PetscErrorCode ierr; 8466 8467 PetscFunctionBegin; 8468 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8469 PetscValidType(mat,1); 8470 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8471 PetscValidPointer(info,3); 8472 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8473 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8474 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8475 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8476 MatCheckPreallocated(mat,1); 8477 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8478 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8479 PetscFunctionReturn(0); 8480 } 8481 8482 /*@ 8483 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8484 ghosted ones. 8485 8486 Not Collective 8487 8488 Input Parameters: 8489 + mat - the matrix 8490 - diag = the diagonal values, including ghost ones 8491 8492 Level: developer 8493 8494 Notes: 8495 Works only for MPIAIJ and MPIBAIJ matrices 8496 8497 .seealso: MatDiagonalScale() 8498 @*/ 8499 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8500 { 8501 PetscErrorCode ierr; 8502 PetscMPIInt size; 8503 8504 PetscFunctionBegin; 8505 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8506 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8507 PetscValidType(mat,1); 8508 8509 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8510 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8511 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8512 if (size == 1) { 8513 PetscInt n,m; 8514 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8515 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8516 if (m == n) { 8517 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8518 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8519 } else { 8520 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8521 } 8522 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8523 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8524 PetscFunctionReturn(0); 8525 } 8526 8527 /*@ 8528 MatGetInertia - Gets the inertia from a factored matrix 8529 8530 Collective on Mat 8531 8532 Input Parameter: 8533 . mat - the matrix 8534 8535 Output Parameters: 8536 + nneg - number of negative eigenvalues 8537 . nzero - number of zero eigenvalues 8538 - npos - number of positive eigenvalues 8539 8540 Level: advanced 8541 8542 Notes: 8543 Matrix must have been factored by MatCholeskyFactor() 8544 8545 8546 @*/ 8547 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8548 { 8549 PetscErrorCode ierr; 8550 8551 PetscFunctionBegin; 8552 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8553 PetscValidType(mat,1); 8554 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8555 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8556 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8557 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8558 PetscFunctionReturn(0); 8559 } 8560 8561 /* ----------------------------------------------------------------*/ 8562 /*@C 8563 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8564 8565 Neighbor-wise Collective on Mat and Vecs 8566 8567 Input Parameters: 8568 + mat - the factored matrix 8569 - b - the right-hand-side vectors 8570 8571 Output Parameter: 8572 . x - the result vectors 8573 8574 Notes: 8575 The vectors b and x cannot be the same. I.e., one cannot 8576 call MatSolves(A,x,x). 8577 8578 Notes: 8579 Most users should employ the simplified KSP interface for linear solvers 8580 instead of working directly with matrix algebra routines such as this. 8581 See, e.g., KSPCreate(). 8582 8583 Level: developer 8584 8585 Concepts: matrices^triangular solves 8586 8587 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8588 @*/ 8589 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8590 { 8591 PetscErrorCode ierr; 8592 8593 PetscFunctionBegin; 8594 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8595 PetscValidType(mat,1); 8596 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8597 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8598 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8599 8600 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8601 MatCheckPreallocated(mat,1); 8602 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8603 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8604 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8605 PetscFunctionReturn(0); 8606 } 8607 8608 /*@ 8609 MatIsSymmetric - Test whether a matrix is symmetric 8610 8611 Collective on Mat 8612 8613 Input Parameter: 8614 + A - the matrix to test 8615 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8616 8617 Output Parameters: 8618 . flg - the result 8619 8620 Notes: 8621 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8622 8623 Level: intermediate 8624 8625 Concepts: matrix^symmetry 8626 8627 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8628 @*/ 8629 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8630 { 8631 PetscErrorCode ierr; 8632 8633 PetscFunctionBegin; 8634 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8635 PetscValidPointer(flg,2); 8636 8637 if (!A->symmetric_set) { 8638 if (!A->ops->issymmetric) { 8639 MatType mattype; 8640 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8641 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8642 } 8643 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8644 if (!tol) { 8645 A->symmetric_set = PETSC_TRUE; 8646 A->symmetric = *flg; 8647 if (A->symmetric) { 8648 A->structurally_symmetric_set = PETSC_TRUE; 8649 A->structurally_symmetric = PETSC_TRUE; 8650 } 8651 } 8652 } else if (A->symmetric) { 8653 *flg = PETSC_TRUE; 8654 } else if (!tol) { 8655 *flg = PETSC_FALSE; 8656 } else { 8657 if (!A->ops->issymmetric) { 8658 MatType mattype; 8659 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8660 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8661 } 8662 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8663 } 8664 PetscFunctionReturn(0); 8665 } 8666 8667 /*@ 8668 MatIsHermitian - Test whether a matrix is Hermitian 8669 8670 Collective on Mat 8671 8672 Input Parameter: 8673 + A - the matrix to test 8674 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8675 8676 Output Parameters: 8677 . flg - the result 8678 8679 Level: intermediate 8680 8681 Concepts: matrix^symmetry 8682 8683 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8684 MatIsSymmetricKnown(), MatIsSymmetric() 8685 @*/ 8686 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8687 { 8688 PetscErrorCode ierr; 8689 8690 PetscFunctionBegin; 8691 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8692 PetscValidPointer(flg,2); 8693 8694 if (!A->hermitian_set) { 8695 if (!A->ops->ishermitian) { 8696 MatType mattype; 8697 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8698 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8699 } 8700 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8701 if (!tol) { 8702 A->hermitian_set = PETSC_TRUE; 8703 A->hermitian = *flg; 8704 if (A->hermitian) { 8705 A->structurally_symmetric_set = PETSC_TRUE; 8706 A->structurally_symmetric = PETSC_TRUE; 8707 } 8708 } 8709 } else if (A->hermitian) { 8710 *flg = PETSC_TRUE; 8711 } else if (!tol) { 8712 *flg = PETSC_FALSE; 8713 } else { 8714 if (!A->ops->ishermitian) { 8715 MatType mattype; 8716 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8717 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8718 } 8719 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8720 } 8721 PetscFunctionReturn(0); 8722 } 8723 8724 /*@ 8725 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8726 8727 Not Collective 8728 8729 Input Parameter: 8730 . A - the matrix to check 8731 8732 Output Parameters: 8733 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8734 - flg - the result 8735 8736 Level: advanced 8737 8738 Concepts: matrix^symmetry 8739 8740 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8741 if you want it explicitly checked 8742 8743 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8744 @*/ 8745 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8746 { 8747 PetscFunctionBegin; 8748 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8749 PetscValidPointer(set,2); 8750 PetscValidPointer(flg,3); 8751 if (A->symmetric_set) { 8752 *set = PETSC_TRUE; 8753 *flg = A->symmetric; 8754 } else { 8755 *set = PETSC_FALSE; 8756 } 8757 PetscFunctionReturn(0); 8758 } 8759 8760 /*@ 8761 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8762 8763 Not Collective 8764 8765 Input Parameter: 8766 . A - the matrix to check 8767 8768 Output Parameters: 8769 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8770 - flg - the result 8771 8772 Level: advanced 8773 8774 Concepts: matrix^symmetry 8775 8776 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8777 if you want it explicitly checked 8778 8779 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8780 @*/ 8781 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8782 { 8783 PetscFunctionBegin; 8784 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8785 PetscValidPointer(set,2); 8786 PetscValidPointer(flg,3); 8787 if (A->hermitian_set) { 8788 *set = PETSC_TRUE; 8789 *flg = A->hermitian; 8790 } else { 8791 *set = PETSC_FALSE; 8792 } 8793 PetscFunctionReturn(0); 8794 } 8795 8796 /*@ 8797 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8798 8799 Collective on Mat 8800 8801 Input Parameter: 8802 . A - the matrix to test 8803 8804 Output Parameters: 8805 . flg - the result 8806 8807 Level: intermediate 8808 8809 Concepts: matrix^symmetry 8810 8811 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8812 @*/ 8813 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8814 { 8815 PetscErrorCode ierr; 8816 8817 PetscFunctionBegin; 8818 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8819 PetscValidPointer(flg,2); 8820 if (!A->structurally_symmetric_set) { 8821 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8822 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8823 8824 A->structurally_symmetric_set = PETSC_TRUE; 8825 } 8826 *flg = A->structurally_symmetric; 8827 PetscFunctionReturn(0); 8828 } 8829 8830 /*@ 8831 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8832 to be communicated to other processors during the MatAssemblyBegin/End() process 8833 8834 Not collective 8835 8836 Input Parameter: 8837 . vec - the vector 8838 8839 Output Parameters: 8840 + nstash - the size of the stash 8841 . reallocs - the number of additional mallocs incurred. 8842 . bnstash - the size of the block stash 8843 - breallocs - the number of additional mallocs incurred.in the block stash 8844 8845 Level: advanced 8846 8847 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8848 8849 @*/ 8850 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8851 { 8852 PetscErrorCode ierr; 8853 8854 PetscFunctionBegin; 8855 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8856 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8857 PetscFunctionReturn(0); 8858 } 8859 8860 /*@C 8861 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8862 parallel layout 8863 8864 Collective on Mat 8865 8866 Input Parameter: 8867 . mat - the matrix 8868 8869 Output Parameter: 8870 + right - (optional) vector that the matrix can be multiplied against 8871 - left - (optional) vector that the matrix vector product can be stored in 8872 8873 Notes: 8874 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(). 8875 8876 Notes: 8877 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8878 8879 Level: advanced 8880 8881 .seealso: MatCreate(), VecDestroy() 8882 @*/ 8883 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8884 { 8885 PetscErrorCode ierr; 8886 8887 PetscFunctionBegin; 8888 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8889 PetscValidType(mat,1); 8890 if (mat->ops->getvecs) { 8891 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8892 } else { 8893 PetscInt rbs,cbs; 8894 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8895 if (right) { 8896 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8897 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8898 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8899 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8900 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8901 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8902 } 8903 if (left) { 8904 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8905 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8906 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8907 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8908 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8909 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8910 } 8911 } 8912 PetscFunctionReturn(0); 8913 } 8914 8915 /*@C 8916 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8917 with default values. 8918 8919 Not Collective 8920 8921 Input Parameters: 8922 . info - the MatFactorInfo data structure 8923 8924 8925 Notes: 8926 The solvers are generally used through the KSP and PC objects, for example 8927 PCLU, PCILU, PCCHOLESKY, PCICC 8928 8929 Level: developer 8930 8931 .seealso: MatFactorInfo 8932 8933 Developer Note: fortran interface is not autogenerated as the f90 8934 interface defintion cannot be generated correctly [due to MatFactorInfo] 8935 8936 @*/ 8937 8938 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8939 { 8940 PetscErrorCode ierr; 8941 8942 PetscFunctionBegin; 8943 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8944 PetscFunctionReturn(0); 8945 } 8946 8947 /*@ 8948 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8949 8950 Collective on Mat 8951 8952 Input Parameters: 8953 + mat - the factored matrix 8954 - is - the index set defining the Schur indices (0-based) 8955 8956 Notes: 8957 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8958 8959 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8960 8961 Level: developer 8962 8963 Concepts: 8964 8965 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8966 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8967 8968 @*/ 8969 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8970 { 8971 PetscErrorCode ierr,(*f)(Mat,IS); 8972 8973 PetscFunctionBegin; 8974 PetscValidType(mat,1); 8975 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8976 PetscValidType(is,2); 8977 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8978 PetscCheckSameComm(mat,1,is,2); 8979 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8980 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8981 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"); 8982 if (mat->schur) { 8983 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8984 } 8985 ierr = (*f)(mat,is);CHKERRQ(ierr); 8986 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8987 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 8988 PetscFunctionReturn(0); 8989 } 8990 8991 /*@ 8992 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8993 8994 Logically Collective on Mat 8995 8996 Input Parameters: 8997 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8998 . S - location where to return the Schur complement, can be NULL 8999 - status - the status of the Schur complement matrix, can be NULL 9000 9001 Notes: 9002 You must call MatFactorSetSchurIS() before calling this routine. 9003 9004 The routine provides a copy of the Schur matrix stored within the solver data structures. 9005 The caller must destroy the object when it is no longer needed. 9006 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9007 9008 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) 9009 9010 Developer Notes: 9011 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9012 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9013 9014 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9015 9016 Level: advanced 9017 9018 References: 9019 9020 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9021 @*/ 9022 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9023 { 9024 PetscErrorCode ierr; 9025 9026 PetscFunctionBegin; 9027 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9028 if (S) PetscValidPointer(S,2); 9029 if (status) PetscValidPointer(status,3); 9030 if (S) { 9031 PetscErrorCode (*f)(Mat,Mat*); 9032 9033 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9034 if (f) { 9035 ierr = (*f)(F,S);CHKERRQ(ierr); 9036 } else { 9037 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9038 } 9039 } 9040 if (status) *status = F->schur_status; 9041 PetscFunctionReturn(0); 9042 } 9043 9044 /*@ 9045 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9046 9047 Logically Collective on Mat 9048 9049 Input Parameters: 9050 + F - the factored matrix obtained by calling MatGetFactor() 9051 . *S - location where to return the Schur complement, can be NULL 9052 - status - the status of the Schur complement matrix, can be NULL 9053 9054 Notes: 9055 You must call MatFactorSetSchurIS() before calling this routine. 9056 9057 Schur complement mode is currently implemented for sequential matrices. 9058 The routine returns a the Schur Complement stored within the data strutures of the solver. 9059 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9060 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9061 9062 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9063 9064 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9065 9066 Level: advanced 9067 9068 References: 9069 9070 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9071 @*/ 9072 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9073 { 9074 PetscFunctionBegin; 9075 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9076 if (S) PetscValidPointer(S,2); 9077 if (status) PetscValidPointer(status,3); 9078 if (S) *S = F->schur; 9079 if (status) *status = F->schur_status; 9080 PetscFunctionReturn(0); 9081 } 9082 9083 /*@ 9084 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9085 9086 Logically Collective on Mat 9087 9088 Input Parameters: 9089 + F - the factored matrix obtained by calling MatGetFactor() 9090 . *S - location where the Schur complement is stored 9091 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9092 9093 Notes: 9094 9095 Level: advanced 9096 9097 References: 9098 9099 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9100 @*/ 9101 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9102 { 9103 PetscErrorCode ierr; 9104 9105 PetscFunctionBegin; 9106 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9107 if (S) { 9108 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9109 *S = NULL; 9110 } 9111 F->schur_status = status; 9112 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9113 PetscFunctionReturn(0); 9114 } 9115 9116 /*@ 9117 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9118 9119 Logically Collective on Mat 9120 9121 Input Parameters: 9122 + F - the factored matrix obtained by calling MatGetFactor() 9123 . rhs - location where the right hand side of the Schur complement system is stored 9124 - sol - location where the solution of the Schur complement system has to be returned 9125 9126 Notes: 9127 The sizes of the vectors should match the size of the Schur complement 9128 9129 Must be called after MatFactorSetSchurIS() 9130 9131 Level: advanced 9132 9133 References: 9134 9135 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9136 @*/ 9137 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9138 { 9139 PetscErrorCode ierr; 9140 9141 PetscFunctionBegin; 9142 PetscValidType(F,1); 9143 PetscValidType(rhs,2); 9144 PetscValidType(sol,3); 9145 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9146 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9147 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9148 PetscCheckSameComm(F,1,rhs,2); 9149 PetscCheckSameComm(F,1,sol,3); 9150 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9151 switch (F->schur_status) { 9152 case MAT_FACTOR_SCHUR_FACTORED: 9153 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9154 break; 9155 case MAT_FACTOR_SCHUR_INVERTED: 9156 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9157 break; 9158 default: 9159 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9160 break; 9161 } 9162 PetscFunctionReturn(0); 9163 } 9164 9165 /*@ 9166 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9167 9168 Logically Collective on Mat 9169 9170 Input Parameters: 9171 + F - the factored matrix obtained by calling MatGetFactor() 9172 . rhs - location where the right hand side of the Schur complement system is stored 9173 - sol - location where the solution of the Schur complement system has to be returned 9174 9175 Notes: 9176 The sizes of the vectors should match the size of the Schur complement 9177 9178 Must be called after MatFactorSetSchurIS() 9179 9180 Level: advanced 9181 9182 References: 9183 9184 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9185 @*/ 9186 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9187 { 9188 PetscErrorCode ierr; 9189 9190 PetscFunctionBegin; 9191 PetscValidType(F,1); 9192 PetscValidType(rhs,2); 9193 PetscValidType(sol,3); 9194 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9195 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9196 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9197 PetscCheckSameComm(F,1,rhs,2); 9198 PetscCheckSameComm(F,1,sol,3); 9199 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9200 switch (F->schur_status) { 9201 case MAT_FACTOR_SCHUR_FACTORED: 9202 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9203 break; 9204 case MAT_FACTOR_SCHUR_INVERTED: 9205 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9206 break; 9207 default: 9208 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9209 break; 9210 } 9211 PetscFunctionReturn(0); 9212 } 9213 9214 /*@ 9215 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9216 9217 Logically Collective on Mat 9218 9219 Input Parameters: 9220 + F - the factored matrix obtained by calling MatGetFactor() 9221 9222 Notes: 9223 Must be called after MatFactorSetSchurIS(). 9224 9225 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9226 9227 Level: advanced 9228 9229 References: 9230 9231 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9232 @*/ 9233 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9234 { 9235 PetscErrorCode ierr; 9236 9237 PetscFunctionBegin; 9238 PetscValidType(F,1); 9239 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9240 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9241 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9242 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9243 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9244 PetscFunctionReturn(0); 9245 } 9246 9247 /*@ 9248 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9249 9250 Logically Collective on Mat 9251 9252 Input Parameters: 9253 + F - the factored matrix obtained by calling MatGetFactor() 9254 9255 Notes: 9256 Must be called after MatFactorSetSchurIS(). 9257 9258 Level: advanced 9259 9260 References: 9261 9262 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9263 @*/ 9264 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9265 { 9266 PetscErrorCode ierr; 9267 9268 PetscFunctionBegin; 9269 PetscValidType(F,1); 9270 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9271 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9272 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9273 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9274 PetscFunctionReturn(0); 9275 } 9276 9277 /*@ 9278 MatPtAP - Creates the matrix product C = P^T * A * P 9279 9280 Neighbor-wise Collective on Mat 9281 9282 Input Parameters: 9283 + A - the matrix 9284 . P - the projection matrix 9285 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9286 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9287 if the result is a dense matrix this is irrelevent 9288 9289 Output Parameters: 9290 . C - the product matrix 9291 9292 Notes: 9293 C will be created and must be destroyed by the user with MatDestroy(). 9294 9295 This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes 9296 which inherit from AIJ. 9297 9298 Level: intermediate 9299 9300 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9301 @*/ 9302 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9303 { 9304 PetscErrorCode ierr; 9305 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9306 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9307 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9308 PetscBool sametype; 9309 9310 PetscFunctionBegin; 9311 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9312 PetscValidType(A,1); 9313 MatCheckPreallocated(A,1); 9314 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9315 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9316 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9317 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9318 PetscValidType(P,2); 9319 MatCheckPreallocated(P,2); 9320 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9321 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9322 9323 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); 9324 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); 9325 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9326 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9327 9328 if (scall == MAT_REUSE_MATRIX) { 9329 PetscValidPointer(*C,5); 9330 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9331 9332 if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX"); 9333 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9334 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9335 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9336 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9337 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9338 PetscFunctionReturn(0); 9339 } 9340 9341 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9342 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9343 9344 fA = A->ops->ptap; 9345 fP = P->ops->ptap; 9346 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9347 if (fP == fA && sametype) { 9348 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9349 ptap = fA; 9350 } else { 9351 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9352 char ptapname[256]; 9353 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9354 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9355 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9356 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9357 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9358 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9359 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); 9360 } 9361 9362 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9363 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9364 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9365 if (A->symmetric_set && A->symmetric) { 9366 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9367 } 9368 PetscFunctionReturn(0); 9369 } 9370 9371 /*@ 9372 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9373 9374 Neighbor-wise Collective on Mat 9375 9376 Input Parameters: 9377 + A - the matrix 9378 - P - the projection matrix 9379 9380 Output Parameters: 9381 . C - the product matrix 9382 9383 Notes: 9384 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9385 the user using MatDeatroy(). 9386 9387 This routine is currently only implemented for pairs of AIJ matrices and classes 9388 which inherit from AIJ. C will be of type MATAIJ. 9389 9390 Level: intermediate 9391 9392 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9393 @*/ 9394 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9395 { 9396 PetscErrorCode ierr; 9397 9398 PetscFunctionBegin; 9399 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9400 PetscValidType(A,1); 9401 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9402 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9403 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9404 PetscValidType(P,2); 9405 MatCheckPreallocated(P,2); 9406 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9407 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9408 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9409 PetscValidType(C,3); 9410 MatCheckPreallocated(C,3); 9411 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9412 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); 9413 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); 9414 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); 9415 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); 9416 MatCheckPreallocated(A,1); 9417 9418 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9419 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9420 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9421 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9422 PetscFunctionReturn(0); 9423 } 9424 9425 /*@ 9426 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9427 9428 Neighbor-wise Collective on Mat 9429 9430 Input Parameters: 9431 + A - the matrix 9432 - P - the projection matrix 9433 9434 Output Parameters: 9435 . C - the (i,j) structure of the product matrix 9436 9437 Notes: 9438 C will be created and must be destroyed by the user with MatDestroy(). 9439 9440 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9441 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9442 this (i,j) structure by calling MatPtAPNumeric(). 9443 9444 Level: intermediate 9445 9446 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9447 @*/ 9448 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9449 { 9450 PetscErrorCode ierr; 9451 9452 PetscFunctionBegin; 9453 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9454 PetscValidType(A,1); 9455 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9456 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9457 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9458 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9459 PetscValidType(P,2); 9460 MatCheckPreallocated(P,2); 9461 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9462 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9463 PetscValidPointer(C,3); 9464 9465 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); 9466 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); 9467 MatCheckPreallocated(A,1); 9468 9469 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9470 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9471 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9472 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9473 9474 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9475 PetscFunctionReturn(0); 9476 } 9477 9478 /*@ 9479 MatRARt - Creates the matrix product C = R * A * R^T 9480 9481 Neighbor-wise Collective on Mat 9482 9483 Input Parameters: 9484 + A - the matrix 9485 . R - the projection matrix 9486 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9487 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9488 if the result is a dense matrix this is irrelevent 9489 9490 Output Parameters: 9491 . C - the product matrix 9492 9493 Notes: 9494 C will be created and must be destroyed by the user with MatDestroy(). 9495 9496 This routine is currently only implemented for pairs of AIJ matrices and classes 9497 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9498 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9499 We recommend using MatPtAP(). 9500 9501 Level: intermediate 9502 9503 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9504 @*/ 9505 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9506 { 9507 PetscErrorCode ierr; 9508 9509 PetscFunctionBegin; 9510 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9511 PetscValidType(A,1); 9512 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9513 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9514 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9515 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9516 PetscValidType(R,2); 9517 MatCheckPreallocated(R,2); 9518 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9519 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9520 PetscValidPointer(C,3); 9521 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); 9522 9523 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9524 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9525 MatCheckPreallocated(A,1); 9526 9527 if (!A->ops->rart) { 9528 Mat Rt; 9529 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9530 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9531 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9532 PetscFunctionReturn(0); 9533 } 9534 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9535 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9536 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9537 PetscFunctionReturn(0); 9538 } 9539 9540 /*@ 9541 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9542 9543 Neighbor-wise Collective on Mat 9544 9545 Input Parameters: 9546 + A - the matrix 9547 - R - the projection matrix 9548 9549 Output Parameters: 9550 . C - the product matrix 9551 9552 Notes: 9553 C must have been created by calling MatRARtSymbolic and must be destroyed by 9554 the user using MatDestroy(). 9555 9556 This routine is currently only implemented for pairs of AIJ matrices and classes 9557 which inherit from AIJ. C will be of type MATAIJ. 9558 9559 Level: intermediate 9560 9561 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9562 @*/ 9563 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9564 { 9565 PetscErrorCode ierr; 9566 9567 PetscFunctionBegin; 9568 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9569 PetscValidType(A,1); 9570 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9571 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9572 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9573 PetscValidType(R,2); 9574 MatCheckPreallocated(R,2); 9575 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9576 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9577 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9578 PetscValidType(C,3); 9579 MatCheckPreallocated(C,3); 9580 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9581 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); 9582 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); 9583 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); 9584 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); 9585 MatCheckPreallocated(A,1); 9586 9587 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9588 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9589 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9590 PetscFunctionReturn(0); 9591 } 9592 9593 /*@ 9594 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9595 9596 Neighbor-wise Collective on Mat 9597 9598 Input Parameters: 9599 + A - the matrix 9600 - R - the projection matrix 9601 9602 Output Parameters: 9603 . C - the (i,j) structure of the product matrix 9604 9605 Notes: 9606 C will be created and must be destroyed by the user with MatDestroy(). 9607 9608 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9609 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9610 this (i,j) structure by calling MatRARtNumeric(). 9611 9612 Level: intermediate 9613 9614 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9615 @*/ 9616 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9617 { 9618 PetscErrorCode ierr; 9619 9620 PetscFunctionBegin; 9621 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9622 PetscValidType(A,1); 9623 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9624 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9625 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9626 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9627 PetscValidType(R,2); 9628 MatCheckPreallocated(R,2); 9629 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9630 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9631 PetscValidPointer(C,3); 9632 9633 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); 9634 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); 9635 MatCheckPreallocated(A,1); 9636 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9637 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9638 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9639 9640 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9641 PetscFunctionReturn(0); 9642 } 9643 9644 /*@ 9645 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9646 9647 Neighbor-wise Collective on Mat 9648 9649 Input Parameters: 9650 + A - the left matrix 9651 . B - the right matrix 9652 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9653 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9654 if the result is a dense matrix this is irrelevent 9655 9656 Output Parameters: 9657 . C - the product matrix 9658 9659 Notes: 9660 Unless scall is MAT_REUSE_MATRIX C will be created. 9661 9662 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 9663 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9664 9665 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9666 actually needed. 9667 9668 If you have many matrices with the same non-zero structure to multiply, you 9669 should either 9670 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9671 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9672 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 9673 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9674 9675 Level: intermediate 9676 9677 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9678 @*/ 9679 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9680 { 9681 PetscErrorCode ierr; 9682 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9683 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9684 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9685 9686 PetscFunctionBegin; 9687 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9688 PetscValidType(A,1); 9689 MatCheckPreallocated(A,1); 9690 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9691 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9692 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9693 PetscValidType(B,2); 9694 MatCheckPreallocated(B,2); 9695 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9696 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9697 PetscValidPointer(C,3); 9698 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9699 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); 9700 if (scall == MAT_REUSE_MATRIX) { 9701 PetscValidPointer(*C,5); 9702 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9703 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9704 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9705 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9706 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9707 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9708 PetscFunctionReturn(0); 9709 } 9710 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9711 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9712 9713 fA = A->ops->matmult; 9714 fB = B->ops->matmult; 9715 if (fB == fA) { 9716 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9717 mult = fB; 9718 } else { 9719 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9720 char multname[256]; 9721 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9722 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9723 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9724 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9725 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9726 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9727 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); 9728 } 9729 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9730 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9731 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9732 PetscFunctionReturn(0); 9733 } 9734 9735 /*@ 9736 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9737 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9738 9739 Neighbor-wise Collective on Mat 9740 9741 Input Parameters: 9742 + A - the left matrix 9743 . B - the right matrix 9744 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9745 if C is a dense matrix this is irrelevent 9746 9747 Output Parameters: 9748 . C - the product matrix 9749 9750 Notes: 9751 Unless scall is MAT_REUSE_MATRIX C will be created. 9752 9753 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9754 actually needed. 9755 9756 This routine is currently implemented for 9757 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9758 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9759 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9760 9761 Level: intermediate 9762 9763 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9764 We should incorporate them into PETSc. 9765 9766 .seealso: MatMatMult(), MatMatMultNumeric() 9767 @*/ 9768 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9769 { 9770 PetscErrorCode ierr; 9771 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9772 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9773 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9774 9775 PetscFunctionBegin; 9776 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9777 PetscValidType(A,1); 9778 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9779 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9780 9781 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9782 PetscValidType(B,2); 9783 MatCheckPreallocated(B,2); 9784 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9785 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9786 PetscValidPointer(C,3); 9787 9788 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); 9789 if (fill == PETSC_DEFAULT) fill = 2.0; 9790 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9791 MatCheckPreallocated(A,1); 9792 9793 Asymbolic = A->ops->matmultsymbolic; 9794 Bsymbolic = B->ops->matmultsymbolic; 9795 if (Asymbolic == Bsymbolic) { 9796 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9797 symbolic = Bsymbolic; 9798 } else { /* dispatch based on the type of A and B */ 9799 char symbolicname[256]; 9800 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9801 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9802 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9803 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9804 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9805 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9806 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); 9807 } 9808 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9809 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9810 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9811 PetscFunctionReturn(0); 9812 } 9813 9814 /*@ 9815 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9816 Call this routine after first calling MatMatMultSymbolic(). 9817 9818 Neighbor-wise Collective on Mat 9819 9820 Input Parameters: 9821 + A - the left matrix 9822 - B - the right matrix 9823 9824 Output Parameters: 9825 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9826 9827 Notes: 9828 C must have been created with MatMatMultSymbolic(). 9829 9830 This routine is currently implemented for 9831 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9832 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9833 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9834 9835 Level: intermediate 9836 9837 .seealso: MatMatMult(), MatMatMultSymbolic() 9838 @*/ 9839 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9840 { 9841 PetscErrorCode ierr; 9842 9843 PetscFunctionBegin; 9844 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9845 PetscFunctionReturn(0); 9846 } 9847 9848 /*@ 9849 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9850 9851 Neighbor-wise Collective on Mat 9852 9853 Input Parameters: 9854 + A - the left matrix 9855 . B - the right matrix 9856 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9857 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9858 9859 Output Parameters: 9860 . C - the product matrix 9861 9862 Notes: 9863 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9864 9865 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9866 9867 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9868 actually needed. 9869 9870 This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class. 9871 9872 Level: intermediate 9873 9874 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9875 @*/ 9876 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9877 { 9878 PetscErrorCode ierr; 9879 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9880 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9881 9882 PetscFunctionBegin; 9883 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9884 PetscValidType(A,1); 9885 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9886 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9887 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9888 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9889 PetscValidType(B,2); 9890 MatCheckPreallocated(B,2); 9891 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9892 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9893 PetscValidPointer(C,3); 9894 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); 9895 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9896 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9897 MatCheckPreallocated(A,1); 9898 9899 fA = A->ops->mattransposemult; 9900 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9901 fB = B->ops->mattransposemult; 9902 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9903 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); 9904 9905 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9906 if (scall == MAT_INITIAL_MATRIX) { 9907 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9908 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9909 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9910 } 9911 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9912 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9913 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9914 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9915 PetscFunctionReturn(0); 9916 } 9917 9918 /*@ 9919 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9920 9921 Neighbor-wise Collective on Mat 9922 9923 Input Parameters: 9924 + A - the left matrix 9925 . B - the right matrix 9926 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9927 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9928 9929 Output Parameters: 9930 . C - the product matrix 9931 9932 Notes: 9933 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9934 9935 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9936 9937 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9938 actually needed. 9939 9940 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9941 which inherit from SeqAIJ. C will be of same type as the input matrices. 9942 9943 Level: intermediate 9944 9945 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9946 @*/ 9947 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9948 { 9949 PetscErrorCode ierr; 9950 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9951 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9952 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 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->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); 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->transposematmult; 9972 fB = B->ops->transposematmult; 9973 if (fB==fA) { 9974 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9975 transposematmult = fA; 9976 } else { 9977 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9978 char multname[256]; 9979 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 9980 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9981 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9982 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9983 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9984 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9985 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); 9986 } 9987 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9988 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9989 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9990 PetscFunctionReturn(0); 9991 } 9992 9993 /*@ 9994 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9995 9996 Neighbor-wise Collective on Mat 9997 9998 Input Parameters: 9999 + A - the left matrix 10000 . B - the middle matrix 10001 . C - the right matrix 10002 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10003 - 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 10004 if the result is a dense matrix this is irrelevent 10005 10006 Output Parameters: 10007 . D - the product matrix 10008 10009 Notes: 10010 Unless scall is MAT_REUSE_MATRIX D will be created. 10011 10012 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10013 10014 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10015 actually needed. 10016 10017 If you have many matrices with the same non-zero structure to multiply, you 10018 should use MAT_REUSE_MATRIX in all calls but the first or 10019 10020 Level: intermediate 10021 10022 .seealso: MatMatMult, MatPtAP() 10023 @*/ 10024 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10025 { 10026 PetscErrorCode ierr; 10027 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10028 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10029 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10030 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 10031 10032 PetscFunctionBegin; 10033 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10034 PetscValidType(A,1); 10035 MatCheckPreallocated(A,1); 10036 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10037 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10038 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10039 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10040 PetscValidType(B,2); 10041 MatCheckPreallocated(B,2); 10042 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10043 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10044 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10045 PetscValidPointer(C,3); 10046 MatCheckPreallocated(C,3); 10047 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10048 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10049 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); 10050 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); 10051 if (scall == MAT_REUSE_MATRIX) { 10052 PetscValidPointer(*D,6); 10053 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 10054 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10055 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10056 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10057 PetscFunctionReturn(0); 10058 } 10059 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10060 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 10061 10062 fA = A->ops->matmatmult; 10063 fB = B->ops->matmatmult; 10064 fC = C->ops->matmatmult; 10065 if (fA == fB && fA == fC) { 10066 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10067 mult = fA; 10068 } else { 10069 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 10070 char multname[256]; 10071 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 10072 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10073 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10074 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10075 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10076 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 10077 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 10078 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 10079 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); 10080 } 10081 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10082 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10083 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10084 PetscFunctionReturn(0); 10085 } 10086 10087 /*@ 10088 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10089 10090 Collective on Mat 10091 10092 Input Parameters: 10093 + mat - the matrix 10094 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10095 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10096 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10097 10098 Output Parameter: 10099 . matredundant - redundant matrix 10100 10101 Notes: 10102 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10103 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10104 10105 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10106 calling it. 10107 10108 Level: advanced 10109 10110 Concepts: subcommunicator 10111 Concepts: duplicate matrix 10112 10113 .seealso: MatDestroy() 10114 @*/ 10115 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10116 { 10117 PetscErrorCode ierr; 10118 MPI_Comm comm; 10119 PetscMPIInt size; 10120 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10121 Mat_Redundant *redund=NULL; 10122 PetscSubcomm psubcomm=NULL; 10123 MPI_Comm subcomm_in=subcomm; 10124 Mat *matseq; 10125 IS isrow,iscol; 10126 PetscBool newsubcomm=PETSC_FALSE; 10127 10128 PetscFunctionBegin; 10129 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10130 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10131 PetscValidPointer(*matredundant,5); 10132 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10133 } 10134 10135 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10136 if (size == 1 || nsubcomm == 1) { 10137 if (reuse == MAT_INITIAL_MATRIX) { 10138 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10139 } else { 10140 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"); 10141 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10142 } 10143 PetscFunctionReturn(0); 10144 } 10145 10146 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10147 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10148 MatCheckPreallocated(mat,1); 10149 10150 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10151 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10152 /* create psubcomm, then get subcomm */ 10153 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10154 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10155 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10156 10157 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10158 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10159 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10160 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10161 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10162 newsubcomm = PETSC_TRUE; 10163 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10164 } 10165 10166 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10167 if (reuse == MAT_INITIAL_MATRIX) { 10168 mloc_sub = PETSC_DECIDE; 10169 nloc_sub = PETSC_DECIDE; 10170 if (bs < 1) { 10171 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10172 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10173 } else { 10174 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10175 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10176 } 10177 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10178 rstart = rend - mloc_sub; 10179 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10180 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10181 } else { /* reuse == MAT_REUSE_MATRIX */ 10182 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"); 10183 /* retrieve subcomm */ 10184 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10185 redund = (*matredundant)->redundant; 10186 isrow = redund->isrow; 10187 iscol = redund->iscol; 10188 matseq = redund->matseq; 10189 } 10190 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10191 10192 /* get matredundant over subcomm */ 10193 if (reuse == MAT_INITIAL_MATRIX) { 10194 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10195 10196 /* create a supporting struct and attach it to C for reuse */ 10197 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10198 (*matredundant)->redundant = redund; 10199 redund->isrow = isrow; 10200 redund->iscol = iscol; 10201 redund->matseq = matseq; 10202 if (newsubcomm) { 10203 redund->subcomm = subcomm; 10204 } else { 10205 redund->subcomm = MPI_COMM_NULL; 10206 } 10207 } else { 10208 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10209 } 10210 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10211 PetscFunctionReturn(0); 10212 } 10213 10214 /*@C 10215 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10216 a given 'mat' object. Each submatrix can span multiple procs. 10217 10218 Collective on Mat 10219 10220 Input Parameters: 10221 + mat - the matrix 10222 . subcomm - the subcommunicator obtained by com_split(comm) 10223 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10224 10225 Output Parameter: 10226 . subMat - 'parallel submatrices each spans a given subcomm 10227 10228 Notes: 10229 The submatrix partition across processors is dictated by 'subComm' a 10230 communicator obtained by com_split(comm). The comm_split 10231 is not restriced to be grouped with consecutive original ranks. 10232 10233 Due the comm_split() usage, the parallel layout of the submatrices 10234 map directly to the layout of the original matrix [wrt the local 10235 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10236 into the 'DiagonalMat' of the subMat, hence it is used directly from 10237 the subMat. However the offDiagMat looses some columns - and this is 10238 reconstructed with MatSetValues() 10239 10240 Level: advanced 10241 10242 Concepts: subcommunicator 10243 Concepts: submatrices 10244 10245 .seealso: MatCreateSubMatrices() 10246 @*/ 10247 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10248 { 10249 PetscErrorCode ierr; 10250 PetscMPIInt commsize,subCommSize; 10251 10252 PetscFunctionBegin; 10253 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10254 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10255 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10256 10257 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"); 10258 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10259 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10260 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10261 PetscFunctionReturn(0); 10262 } 10263 10264 /*@ 10265 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10266 10267 Not Collective 10268 10269 Input Arguments: 10270 mat - matrix to extract local submatrix from 10271 isrow - local row indices for submatrix 10272 iscol - local column indices for submatrix 10273 10274 Output Arguments: 10275 submat - the submatrix 10276 10277 Level: intermediate 10278 10279 Notes: 10280 The submat should be returned with MatRestoreLocalSubMatrix(). 10281 10282 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10283 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10284 10285 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10286 MatSetValuesBlockedLocal() will also be implemented. 10287 10288 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10289 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10290 10291 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10292 @*/ 10293 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10294 { 10295 PetscErrorCode ierr; 10296 10297 PetscFunctionBegin; 10298 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10299 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10300 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10301 PetscCheckSameComm(isrow,2,iscol,3); 10302 PetscValidPointer(submat,4); 10303 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10304 10305 if (mat->ops->getlocalsubmatrix) { 10306 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10307 } else { 10308 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10309 } 10310 PetscFunctionReturn(0); 10311 } 10312 10313 /*@ 10314 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10315 10316 Not Collective 10317 10318 Input Arguments: 10319 mat - matrix to extract local submatrix from 10320 isrow - local row indices for submatrix 10321 iscol - local column indices for submatrix 10322 submat - the submatrix 10323 10324 Level: intermediate 10325 10326 .seealso: MatGetLocalSubMatrix() 10327 @*/ 10328 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10329 { 10330 PetscErrorCode ierr; 10331 10332 PetscFunctionBegin; 10333 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10334 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10335 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10336 PetscCheckSameComm(isrow,2,iscol,3); 10337 PetscValidPointer(submat,4); 10338 if (*submat) { 10339 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10340 } 10341 10342 if (mat->ops->restorelocalsubmatrix) { 10343 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10344 } else { 10345 ierr = MatDestroy(submat);CHKERRQ(ierr); 10346 } 10347 *submat = NULL; 10348 PetscFunctionReturn(0); 10349 } 10350 10351 /* --------------------------------------------------------*/ 10352 /*@ 10353 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10354 10355 Collective on Mat 10356 10357 Input Parameter: 10358 . mat - the matrix 10359 10360 Output Parameter: 10361 . is - if any rows have zero diagonals this contains the list of them 10362 10363 Level: developer 10364 10365 Concepts: matrix-vector product 10366 10367 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10368 @*/ 10369 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10370 { 10371 PetscErrorCode ierr; 10372 10373 PetscFunctionBegin; 10374 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10375 PetscValidType(mat,1); 10376 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10377 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10378 10379 if (!mat->ops->findzerodiagonals) { 10380 Vec diag; 10381 const PetscScalar *a; 10382 PetscInt *rows; 10383 PetscInt rStart, rEnd, r, nrow = 0; 10384 10385 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10386 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10387 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10388 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10389 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10390 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10391 nrow = 0; 10392 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10393 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10394 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10395 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10396 } else { 10397 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10398 } 10399 PetscFunctionReturn(0); 10400 } 10401 10402 /*@ 10403 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10404 10405 Collective on Mat 10406 10407 Input Parameter: 10408 . mat - the matrix 10409 10410 Output Parameter: 10411 . is - contains the list of rows with off block diagonal entries 10412 10413 Level: developer 10414 10415 Concepts: matrix-vector product 10416 10417 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10418 @*/ 10419 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10420 { 10421 PetscErrorCode ierr; 10422 10423 PetscFunctionBegin; 10424 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10425 PetscValidType(mat,1); 10426 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10427 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10428 10429 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10430 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10431 PetscFunctionReturn(0); 10432 } 10433 10434 /*@C 10435 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10436 10437 Collective on Mat 10438 10439 Input Parameters: 10440 . mat - the matrix 10441 10442 Output Parameters: 10443 . values - the block inverses in column major order (FORTRAN-like) 10444 10445 Note: 10446 This routine is not available from Fortran. 10447 10448 Level: advanced 10449 10450 .seealso: MatInvertBockDiagonalMat 10451 @*/ 10452 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10453 { 10454 PetscErrorCode ierr; 10455 10456 PetscFunctionBegin; 10457 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10458 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10459 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10460 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10461 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10462 PetscFunctionReturn(0); 10463 } 10464 10465 /*@C 10466 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10467 10468 Collective on Mat 10469 10470 Input Parameters: 10471 + mat - the matrix 10472 . nblocks - the number of blocks 10473 - bsizes - the size of each block 10474 10475 Output Parameters: 10476 . values - the block inverses in column major order (FORTRAN-like) 10477 10478 Note: 10479 This routine is not available from Fortran. 10480 10481 Level: advanced 10482 10483 .seealso: MatInvertBockDiagonal() 10484 @*/ 10485 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10486 { 10487 PetscErrorCode ierr; 10488 10489 PetscFunctionBegin; 10490 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10491 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10492 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10493 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10494 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10495 PetscFunctionReturn(0); 10496 } 10497 10498 /*@ 10499 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10500 10501 Collective on Mat 10502 10503 Input Parameters: 10504 . A - the matrix 10505 10506 Output Parameters: 10507 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10508 10509 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10510 10511 Level: advanced 10512 10513 .seealso: MatInvertBockDiagonal() 10514 @*/ 10515 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10516 { 10517 PetscErrorCode ierr; 10518 const PetscScalar *vals; 10519 PetscInt *dnnz; 10520 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10521 10522 PetscFunctionBegin; 10523 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10524 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10525 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10526 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10527 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10528 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10529 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10530 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10531 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10532 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10533 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10534 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10535 for (i = rstart/bs; i < rend/bs; i++) { 10536 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10537 } 10538 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10539 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10540 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10541 PetscFunctionReturn(0); 10542 } 10543 10544 /*@C 10545 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10546 via MatTransposeColoringCreate(). 10547 10548 Collective on MatTransposeColoring 10549 10550 Input Parameter: 10551 . c - coloring context 10552 10553 Level: intermediate 10554 10555 .seealso: MatTransposeColoringCreate() 10556 @*/ 10557 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10558 { 10559 PetscErrorCode ierr; 10560 MatTransposeColoring matcolor=*c; 10561 10562 PetscFunctionBegin; 10563 if (!matcolor) PetscFunctionReturn(0); 10564 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10565 10566 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10567 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10568 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10569 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10570 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10571 if (matcolor->brows>0) { 10572 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10573 } 10574 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10575 PetscFunctionReturn(0); 10576 } 10577 10578 /*@C 10579 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10580 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10581 MatTransposeColoring to sparse B. 10582 10583 Collective on MatTransposeColoring 10584 10585 Input Parameters: 10586 + B - sparse matrix B 10587 . Btdense - symbolic dense matrix B^T 10588 - coloring - coloring context created with MatTransposeColoringCreate() 10589 10590 Output Parameter: 10591 . Btdense - dense matrix B^T 10592 10593 Level: advanced 10594 10595 Notes: 10596 These are used internally for some implementations of MatRARt() 10597 10598 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10599 10600 .keywords: coloring 10601 @*/ 10602 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10603 { 10604 PetscErrorCode ierr; 10605 10606 PetscFunctionBegin; 10607 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10608 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10609 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10610 10611 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10612 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10613 PetscFunctionReturn(0); 10614 } 10615 10616 /*@C 10617 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10618 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10619 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10620 Csp from Cden. 10621 10622 Collective on MatTransposeColoring 10623 10624 Input Parameters: 10625 + coloring - coloring context created with MatTransposeColoringCreate() 10626 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10627 10628 Output Parameter: 10629 . Csp - sparse matrix 10630 10631 Level: advanced 10632 10633 Notes: 10634 These are used internally for some implementations of MatRARt() 10635 10636 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10637 10638 .keywords: coloring 10639 @*/ 10640 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10641 { 10642 PetscErrorCode ierr; 10643 10644 PetscFunctionBegin; 10645 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10646 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10647 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10648 10649 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10650 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10651 PetscFunctionReturn(0); 10652 } 10653 10654 /*@C 10655 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10656 10657 Collective on Mat 10658 10659 Input Parameters: 10660 + mat - the matrix product C 10661 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10662 10663 Output Parameter: 10664 . color - the new coloring context 10665 10666 Level: intermediate 10667 10668 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10669 MatTransColoringApplyDenToSp() 10670 @*/ 10671 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10672 { 10673 MatTransposeColoring c; 10674 MPI_Comm comm; 10675 PetscErrorCode ierr; 10676 10677 PetscFunctionBegin; 10678 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10679 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10680 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10681 10682 c->ctype = iscoloring->ctype; 10683 if (mat->ops->transposecoloringcreate) { 10684 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10685 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10686 10687 *color = c; 10688 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10689 PetscFunctionReturn(0); 10690 } 10691 10692 /*@ 10693 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10694 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10695 same, otherwise it will be larger 10696 10697 Not Collective 10698 10699 Input Parameter: 10700 . A - the matrix 10701 10702 Output Parameter: 10703 . state - the current state 10704 10705 Notes: 10706 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10707 different matrices 10708 10709 Level: intermediate 10710 10711 @*/ 10712 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10713 { 10714 PetscFunctionBegin; 10715 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10716 *state = mat->nonzerostate; 10717 PetscFunctionReturn(0); 10718 } 10719 10720 /*@ 10721 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10722 matrices from each processor 10723 10724 Collective on MPI_Comm 10725 10726 Input Parameters: 10727 + comm - the communicators the parallel matrix will live on 10728 . seqmat - the input sequential matrices 10729 . n - number of local columns (or PETSC_DECIDE) 10730 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10731 10732 Output Parameter: 10733 . mpimat - the parallel matrix generated 10734 10735 Level: advanced 10736 10737 Notes: 10738 The number of columns of the matrix in EACH processor MUST be the same. 10739 10740 @*/ 10741 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10742 { 10743 PetscErrorCode ierr; 10744 10745 PetscFunctionBegin; 10746 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10747 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"); 10748 10749 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10750 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10751 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10752 PetscFunctionReturn(0); 10753 } 10754 10755 /*@ 10756 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10757 ranks' ownership ranges. 10758 10759 Collective on A 10760 10761 Input Parameters: 10762 + A - the matrix to create subdomains from 10763 - N - requested number of subdomains 10764 10765 10766 Output Parameters: 10767 + n - number of subdomains resulting on this rank 10768 - iss - IS list with indices of subdomains on this rank 10769 10770 Level: advanced 10771 10772 Notes: 10773 number of subdomains must be smaller than the communicator size 10774 @*/ 10775 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10776 { 10777 MPI_Comm comm,subcomm; 10778 PetscMPIInt size,rank,color; 10779 PetscInt rstart,rend,k; 10780 PetscErrorCode ierr; 10781 10782 PetscFunctionBegin; 10783 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10784 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10785 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10786 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); 10787 *n = 1; 10788 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10789 color = rank/k; 10790 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10791 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10792 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10793 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10794 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10795 PetscFunctionReturn(0); 10796 } 10797 10798 /*@ 10799 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10800 10801 If the interpolation and restriction operators are the same, uses MatPtAP. 10802 If they are not the same, use MatMatMatMult. 10803 10804 Once the coarse grid problem is constructed, correct for interpolation operators 10805 that are not of full rank, which can legitimately happen in the case of non-nested 10806 geometric multigrid. 10807 10808 Input Parameters: 10809 + restrct - restriction operator 10810 . dA - fine grid matrix 10811 . interpolate - interpolation operator 10812 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10813 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10814 10815 Output Parameters: 10816 . A - the Galerkin coarse matrix 10817 10818 Options Database Key: 10819 . -pc_mg_galerkin <both,pmat,mat,none> 10820 10821 Level: developer 10822 10823 .keywords: MG, multigrid, Galerkin 10824 10825 .seealso: MatPtAP(), MatMatMatMult() 10826 @*/ 10827 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10828 { 10829 PetscErrorCode ierr; 10830 IS zerorows; 10831 Vec diag; 10832 10833 PetscFunctionBegin; 10834 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10835 /* Construct the coarse grid matrix */ 10836 if (interpolate == restrct) { 10837 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10838 } else { 10839 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10840 } 10841 10842 /* If the interpolation matrix is not of full rank, A will have zero rows. 10843 This can legitimately happen in the case of non-nested geometric multigrid. 10844 In that event, we set the rows of the matrix to the rows of the identity, 10845 ignoring the equations (as the RHS will also be zero). */ 10846 10847 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10848 10849 if (zerorows != NULL) { /* if there are any zero rows */ 10850 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10851 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10852 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10853 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10854 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10855 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10856 } 10857 PetscFunctionReturn(0); 10858 } 10859 10860 /*@C 10861 MatSetOperation - Allows user to set a matrix operation for any matrix type 10862 10863 Logically Collective on Mat 10864 10865 Input Parameters: 10866 + mat - the matrix 10867 . op - the name of the operation 10868 - f - the function that provides the operation 10869 10870 Level: developer 10871 10872 Usage: 10873 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10874 $ ierr = MatCreateXXX(comm,...&A); 10875 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10876 10877 Notes: 10878 See the file include/petscmat.h for a complete list of matrix 10879 operations, which all have the form MATOP_<OPERATION>, where 10880 <OPERATION> is the name (in all capital letters) of the 10881 user interface routine (e.g., MatMult() -> MATOP_MULT). 10882 10883 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10884 sequence as the usual matrix interface routines, since they 10885 are intended to be accessed via the usual matrix interface 10886 routines, e.g., 10887 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10888 10889 In particular each function MUST return an error code of 0 on success and 10890 nonzero on failure. 10891 10892 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10893 10894 .keywords: matrix, set, operation 10895 10896 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10897 @*/ 10898 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10899 { 10900 PetscFunctionBegin; 10901 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10902 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10903 mat->ops->viewnative = mat->ops->view; 10904 } 10905 (((void(**)(void))mat->ops)[op]) = f; 10906 PetscFunctionReturn(0); 10907 } 10908 10909 /*@C 10910 MatGetOperation - Gets a matrix operation for any matrix type. 10911 10912 Not Collective 10913 10914 Input Parameters: 10915 + mat - the matrix 10916 - op - the name of the operation 10917 10918 Output Parameter: 10919 . f - the function that provides the operation 10920 10921 Level: developer 10922 10923 Usage: 10924 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10925 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10926 10927 Notes: 10928 See the file include/petscmat.h for a complete list of matrix 10929 operations, which all have the form MATOP_<OPERATION>, where 10930 <OPERATION> is the name (in all capital letters) of the 10931 user interface routine (e.g., MatMult() -> MATOP_MULT). 10932 10933 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10934 10935 .keywords: matrix, get, operation 10936 10937 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10938 @*/ 10939 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10940 { 10941 PetscFunctionBegin; 10942 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10943 *f = (((void (**)(void))mat->ops)[op]); 10944 PetscFunctionReturn(0); 10945 } 10946 10947 /*@ 10948 MatHasOperation - Determines whether the given matrix supports the particular 10949 operation. 10950 10951 Not Collective 10952 10953 Input Parameters: 10954 + mat - the matrix 10955 - op - the operation, for example, MATOP_GET_DIAGONAL 10956 10957 Output Parameter: 10958 . has - either PETSC_TRUE or PETSC_FALSE 10959 10960 Level: advanced 10961 10962 Notes: 10963 See the file include/petscmat.h for a complete list of matrix 10964 operations, which all have the form MATOP_<OPERATION>, where 10965 <OPERATION> is the name (in all capital letters) of the 10966 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10967 10968 .keywords: matrix, has, operation 10969 10970 .seealso: MatCreateShell() 10971 @*/ 10972 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10973 { 10974 PetscErrorCode ierr; 10975 10976 PetscFunctionBegin; 10977 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10978 PetscValidType(mat,1); 10979 PetscValidPointer(has,3); 10980 if (mat->ops->hasoperation) { 10981 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10982 } else { 10983 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10984 else { 10985 *has = PETSC_FALSE; 10986 if (op == MATOP_CREATE_SUBMATRIX) { 10987 PetscMPIInt size; 10988 10989 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10990 if (size == 1) { 10991 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10992 } 10993 } 10994 } 10995 } 10996 PetscFunctionReturn(0); 10997 } 10998 10999 /*@ 11000 MatHasCongruentLayouts - Determines whether the rows and columns layouts 11001 of the matrix are congruent 11002 11003 Collective on mat 11004 11005 Input Parameters: 11006 . mat - the matrix 11007 11008 Output Parameter: 11009 . cong - either PETSC_TRUE or PETSC_FALSE 11010 11011 Level: beginner 11012 11013 Notes: 11014 11015 .keywords: matrix, has 11016 11017 .seealso: MatCreate(), MatSetSizes() 11018 @*/ 11019 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11020 { 11021 PetscErrorCode ierr; 11022 11023 PetscFunctionBegin; 11024 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11025 PetscValidType(mat,1); 11026 PetscValidPointer(cong,2); 11027 if (!mat->rmap || !mat->cmap) { 11028 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11029 PetscFunctionReturn(0); 11030 } 11031 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11032 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 11033 if (*cong) mat->congruentlayouts = 1; 11034 else mat->congruentlayouts = 0; 11035 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11036 PetscFunctionReturn(0); 11037 } 11038