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