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