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, MAT_CUSPARSESolveAnalysis; 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 = PetscStrcmp(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 /* try with base classes inext->mtype */ 4462 next = MatSolverTypeHolders; 4463 while (next) { 4464 inext = next->handlers; 4465 while (inext) { 4466 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4467 if (flg && inext->createfactor[(int)ftype-1]) { 4468 if (foundtype) *foundtype = PETSC_TRUE; 4469 if (foundmtype) *foundmtype = PETSC_TRUE; 4470 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4471 PetscFunctionReturn(0); 4472 } 4473 inext = inext->next; 4474 } 4475 next = next->next; 4476 } 4477 } 4478 PetscFunctionReturn(0); 4479 } 4480 4481 PetscErrorCode MatSolverTypeDestroy(void) 4482 { 4483 PetscErrorCode ierr; 4484 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4485 MatSolverTypeForSpecifcType inext,iprev; 4486 4487 PetscFunctionBegin; 4488 while (next) { 4489 ierr = PetscFree(next->name);CHKERRQ(ierr); 4490 inext = next->handlers; 4491 while (inext) { 4492 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4493 iprev = inext; 4494 inext = inext->next; 4495 ierr = PetscFree(iprev);CHKERRQ(ierr); 4496 } 4497 prev = next; 4498 next = next->next; 4499 ierr = PetscFree(prev);CHKERRQ(ierr); 4500 } 4501 MatSolverTypeHolders = NULL; 4502 PetscFunctionReturn(0); 4503 } 4504 4505 /*@C 4506 MatFactorGetUseOrdering - Indicates if the factorization uses the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4507 4508 Logically Collective on Mat 4509 4510 Input Parameters: 4511 . mat - the matrix 4512 4513 Output Parameters: 4514 . flg - PETSC_TRUE if uses the ordering 4515 4516 Notes: 4517 Most internal PETSc factorizations use the ordering past to the factorization routine but external 4518 packages do no, thus we want to skip the ordering when it is not needed. 4519 4520 Level: developer 4521 4522 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4523 @*/ 4524 PetscErrorCode MatFactorGetUseOrdering(Mat mat, PetscBool *flg) 4525 { 4526 PetscFunctionBegin; 4527 *flg = mat->useordering; 4528 PetscFunctionReturn(0); 4529 } 4530 4531 /*@C 4532 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4533 4534 Collective on Mat 4535 4536 Input Parameters: 4537 + mat - the matrix 4538 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4539 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4540 4541 Output Parameters: 4542 . f - the factor matrix used with MatXXFactorSymbolic() calls 4543 4544 Notes: 4545 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4546 such as pastix, superlu, mumps etc. 4547 4548 PETSc must have been ./configure to use the external solver, using the option --download-package 4549 4550 Developer Notes: 4551 This should actually be called MatCreateFactor() since it creates a new factor object 4552 4553 Level: intermediate 4554 4555 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatFactorGetUseOrdering(), MatSolverTypeRegister() 4556 @*/ 4557 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4558 { 4559 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4560 PetscBool foundtype,foundmtype; 4561 4562 PetscFunctionBegin; 4563 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4564 PetscValidType(mat,1); 4565 4566 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4567 MatCheckPreallocated(mat,1); 4568 4569 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv);CHKERRQ(ierr); 4570 if (!foundtype) { 4571 if (type) { 4572 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); 4573 } else { 4574 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); 4575 } 4576 } 4577 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4578 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); 4579 4580 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4581 PetscFunctionReturn(0); 4582 } 4583 4584 /*@C 4585 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4586 4587 Not Collective 4588 4589 Input Parameters: 4590 + mat - the matrix 4591 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4592 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4593 4594 Output Parameter: 4595 . flg - PETSC_TRUE if the factorization is available 4596 4597 Notes: 4598 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4599 such as pastix, superlu, mumps etc. 4600 4601 PETSc must have been ./configure to use the external solver, using the option --download-package 4602 4603 Developer Notes: 4604 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4605 4606 Level: intermediate 4607 4608 .seealso: MatCopy(), MatDuplicate(), MatGetFactor(), MatSolverTypeRegister() 4609 @*/ 4610 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4611 { 4612 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4613 4614 PetscFunctionBegin; 4615 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4616 PetscValidType(mat,1); 4617 4618 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4619 MatCheckPreallocated(mat,1); 4620 4621 *flg = PETSC_FALSE; 4622 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4623 if (gconv) { 4624 *flg = PETSC_TRUE; 4625 } 4626 PetscFunctionReturn(0); 4627 } 4628 4629 #include <petscdmtypes.h> 4630 4631 /*@ 4632 MatDuplicate - Duplicates a matrix including the non-zero structure. 4633 4634 Collective on Mat 4635 4636 Input Parameters: 4637 + mat - the matrix 4638 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4639 See the manual page for MatDuplicateOption for an explanation of these options. 4640 4641 Output Parameter: 4642 . M - pointer to place new matrix 4643 4644 Level: intermediate 4645 4646 Notes: 4647 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4648 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. 4649 4650 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4651 @*/ 4652 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4653 { 4654 PetscErrorCode ierr; 4655 Mat B; 4656 PetscInt i; 4657 DM dm; 4658 void (*viewf)(void); 4659 4660 PetscFunctionBegin; 4661 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4662 PetscValidType(mat,1); 4663 PetscValidPointer(M,3); 4664 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4665 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4666 MatCheckPreallocated(mat,1); 4667 4668 *M = NULL; 4669 if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name); 4670 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4671 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4672 B = *M; 4673 4674 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4675 if (viewf) { 4676 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4677 } 4678 4679 B->stencil.dim = mat->stencil.dim; 4680 B->stencil.noc = mat->stencil.noc; 4681 for (i=0; i<=mat->stencil.dim; i++) { 4682 B->stencil.dims[i] = mat->stencil.dims[i]; 4683 B->stencil.starts[i] = mat->stencil.starts[i]; 4684 } 4685 4686 B->nooffproczerorows = mat->nooffproczerorows; 4687 B->nooffprocentries = mat->nooffprocentries; 4688 4689 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4690 if (dm) { 4691 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4692 } 4693 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4694 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4695 PetscFunctionReturn(0); 4696 } 4697 4698 /*@ 4699 MatGetDiagonal - Gets the diagonal of a matrix. 4700 4701 Logically Collective on Mat 4702 4703 Input Parameters: 4704 + mat - the matrix 4705 - v - the vector for storing the diagonal 4706 4707 Output Parameter: 4708 . v - the diagonal of the matrix 4709 4710 Level: intermediate 4711 4712 Note: 4713 Currently only correct in parallel for square matrices. 4714 4715 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4716 @*/ 4717 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4718 { 4719 PetscErrorCode ierr; 4720 4721 PetscFunctionBegin; 4722 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4723 PetscValidType(mat,1); 4724 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4725 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4726 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4727 MatCheckPreallocated(mat,1); 4728 4729 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4730 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4731 PetscFunctionReturn(0); 4732 } 4733 4734 /*@C 4735 MatGetRowMin - Gets the minimum value (of the real part) of each 4736 row of the matrix 4737 4738 Logically Collective on Mat 4739 4740 Input Parameters: 4741 . mat - the matrix 4742 4743 Output Parameter: 4744 + v - the vector for storing the maximums 4745 - idx - the indices of the column found for each row (optional) 4746 4747 Level: intermediate 4748 4749 Notes: 4750 The result of this call are the same as if one converted the matrix to dense format 4751 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4752 4753 This code is only implemented for a couple of matrix formats. 4754 4755 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4756 MatGetRowMax() 4757 @*/ 4758 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4759 { 4760 PetscErrorCode ierr; 4761 4762 PetscFunctionBegin; 4763 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4764 PetscValidType(mat,1); 4765 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4766 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4767 4768 if (!mat->cmap->N) { 4769 ierr = VecSet(v,PETSC_MAX_REAL);CHKERRQ(ierr); 4770 if (idx) { 4771 PetscInt i,m = mat->rmap->n; 4772 for (i=0; i<m; i++) idx[i] = -1; 4773 } 4774 } else { 4775 if (!mat->ops->getrowmin) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4776 MatCheckPreallocated(mat,1); 4777 } 4778 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4779 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4780 PetscFunctionReturn(0); 4781 } 4782 4783 /*@C 4784 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4785 row of the matrix 4786 4787 Logically Collective on Mat 4788 4789 Input Parameters: 4790 . mat - the matrix 4791 4792 Output Parameter: 4793 + v - the vector for storing the minimums 4794 - idx - the indices of the column found for each row (or NULL if not needed) 4795 4796 Level: intermediate 4797 4798 Notes: 4799 if a row is completely empty or has only 0.0 values then the idx[] value for that 4800 row is 0 (the first column). 4801 4802 This code is only implemented for a couple of matrix formats. 4803 4804 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4805 @*/ 4806 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4807 { 4808 PetscErrorCode ierr; 4809 4810 PetscFunctionBegin; 4811 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4812 PetscValidType(mat,1); 4813 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4814 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4815 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4816 4817 if (!mat->cmap->N) { 4818 ierr = VecSet(v,0.0);CHKERRQ(ierr); 4819 if (idx) { 4820 PetscInt i,m = mat->rmap->n; 4821 for (i=0; i<m; i++) idx[i] = -1; 4822 } 4823 } else { 4824 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4825 MatCheckPreallocated(mat,1); 4826 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4827 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4828 } 4829 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4830 PetscFunctionReturn(0); 4831 } 4832 4833 /*@C 4834 MatGetRowMax - Gets the maximum value (of the real part) of each 4835 row of the matrix 4836 4837 Logically Collective on Mat 4838 4839 Input Parameters: 4840 . mat - the matrix 4841 4842 Output Parameter: 4843 + v - the vector for storing the maximums 4844 - idx - the indices of the column found for each row (optional) 4845 4846 Level: intermediate 4847 4848 Notes: 4849 The result of this call are the same as if one converted the matrix to dense format 4850 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4851 4852 This code is only implemented for a couple of matrix formats. 4853 4854 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4855 @*/ 4856 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4857 { 4858 PetscErrorCode ierr; 4859 4860 PetscFunctionBegin; 4861 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4862 PetscValidType(mat,1); 4863 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4864 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4865 4866 if (!mat->cmap->N) { 4867 ierr = VecSet(v,PETSC_MIN_REAL);CHKERRQ(ierr); 4868 if (idx) { 4869 PetscInt i,m = mat->rmap->n; 4870 for (i=0; i<m; i++) idx[i] = -1; 4871 } 4872 } else { 4873 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4874 MatCheckPreallocated(mat,1); 4875 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4876 } 4877 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4878 PetscFunctionReturn(0); 4879 } 4880 4881 /*@C 4882 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4883 row of the matrix 4884 4885 Logically Collective on Mat 4886 4887 Input Parameters: 4888 . mat - the matrix 4889 4890 Output Parameter: 4891 + v - the vector for storing the maximums 4892 - idx - the indices of the column found for each row (or NULL if not needed) 4893 4894 Level: intermediate 4895 4896 Notes: 4897 if a row is completely empty or has only 0.0 values then the idx[] value for that 4898 row is 0 (the first column). 4899 4900 This code is only implemented for a couple of matrix formats. 4901 4902 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4903 @*/ 4904 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4905 { 4906 PetscErrorCode ierr; 4907 4908 PetscFunctionBegin; 4909 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4910 PetscValidType(mat,1); 4911 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4912 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4913 4914 if (!mat->cmap->N) { 4915 ierr = VecSet(v,0.0);CHKERRQ(ierr); 4916 if (idx) { 4917 PetscInt i,m = mat->rmap->n; 4918 for (i=0; i<m; i++) idx[i] = -1; 4919 } 4920 } else { 4921 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4922 MatCheckPreallocated(mat,1); 4923 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4924 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4925 } 4926 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4927 PetscFunctionReturn(0); 4928 } 4929 4930 /*@ 4931 MatGetRowSum - Gets the sum of each row of the matrix 4932 4933 Logically or Neighborhood Collective on Mat 4934 4935 Input Parameters: 4936 . mat - the matrix 4937 4938 Output Parameter: 4939 . v - the vector for storing the sum of rows 4940 4941 Level: intermediate 4942 4943 Notes: 4944 This code is slow since it is not currently specialized for different formats 4945 4946 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4947 @*/ 4948 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4949 { 4950 Vec ones; 4951 PetscErrorCode ierr; 4952 4953 PetscFunctionBegin; 4954 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4955 PetscValidType(mat,1); 4956 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4957 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4958 MatCheckPreallocated(mat,1); 4959 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4960 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4961 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4962 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4963 PetscFunctionReturn(0); 4964 } 4965 4966 /*@ 4967 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4968 4969 Collective on Mat 4970 4971 Input Parameter: 4972 + mat - the matrix to transpose 4973 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4974 4975 Output Parameters: 4976 . B - the transpose 4977 4978 Notes: 4979 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4980 4981 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4982 4983 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4984 4985 Level: intermediate 4986 4987 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4988 @*/ 4989 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4990 { 4991 PetscErrorCode ierr; 4992 4993 PetscFunctionBegin; 4994 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4995 PetscValidType(mat,1); 4996 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4997 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4998 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4999 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5000 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5001 MatCheckPreallocated(mat,1); 5002 5003 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 5004 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 5005 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 5006 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 5007 PetscFunctionReturn(0); 5008 } 5009 5010 /*@ 5011 MatIsTranspose - Test whether a matrix is another one's transpose, 5012 or its own, in which case it tests symmetry. 5013 5014 Collective on Mat 5015 5016 Input Parameter: 5017 + A - the matrix to test 5018 - B - the matrix to test against, this can equal the first parameter 5019 5020 Output Parameters: 5021 . flg - the result 5022 5023 Notes: 5024 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5025 has a running time of the order of the number of nonzeros; the parallel 5026 test involves parallel copies of the block-offdiagonal parts of the matrix. 5027 5028 Level: intermediate 5029 5030 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 5031 @*/ 5032 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5033 { 5034 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5035 5036 PetscFunctionBegin; 5037 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5038 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5039 PetscValidBoolPointer(flg,3); 5040 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 5041 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 5042 *flg = PETSC_FALSE; 5043 if (f && g) { 5044 if (f == g) { 5045 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5046 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5047 } else { 5048 MatType mattype; 5049 if (!f) { 5050 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 5051 } else { 5052 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 5053 } 5054 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5055 } 5056 PetscFunctionReturn(0); 5057 } 5058 5059 /*@ 5060 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5061 5062 Collective on Mat 5063 5064 Input Parameter: 5065 + mat - the matrix to transpose and complex conjugate 5066 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 5067 5068 Output Parameters: 5069 . B - the Hermitian 5070 5071 Level: intermediate 5072 5073 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 5074 @*/ 5075 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5076 { 5077 PetscErrorCode ierr; 5078 5079 PetscFunctionBegin; 5080 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 5081 #if defined(PETSC_USE_COMPLEX) 5082 ierr = MatConjugate(*B);CHKERRQ(ierr); 5083 #endif 5084 PetscFunctionReturn(0); 5085 } 5086 5087 /*@ 5088 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5089 5090 Collective on Mat 5091 5092 Input Parameter: 5093 + A - the matrix to test 5094 - B - the matrix to test against, this can equal the first parameter 5095 5096 Output Parameters: 5097 . flg - the result 5098 5099 Notes: 5100 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5101 has a running time of the order of the number of nonzeros; the parallel 5102 test involves parallel copies of the block-offdiagonal parts of the matrix. 5103 5104 Level: intermediate 5105 5106 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 5107 @*/ 5108 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5109 { 5110 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5111 5112 PetscFunctionBegin; 5113 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5114 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5115 PetscValidBoolPointer(flg,3); 5116 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 5117 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 5118 if (f && g) { 5119 if (f==g) { 5120 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5121 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5122 } 5123 PetscFunctionReturn(0); 5124 } 5125 5126 /*@ 5127 MatPermute - Creates a new matrix with rows and columns permuted from the 5128 original. 5129 5130 Collective on Mat 5131 5132 Input Parameters: 5133 + mat - the matrix to permute 5134 . row - row permutation, each processor supplies only the permutation for its rows 5135 - col - column permutation, each processor supplies only the permutation for its columns 5136 5137 Output Parameters: 5138 . B - the permuted matrix 5139 5140 Level: advanced 5141 5142 Note: 5143 The index sets map from row/col of permuted matrix to row/col of original matrix. 5144 The index sets should be on the same communicator as Mat and have the same local sizes. 5145 5146 .seealso: MatGetOrdering(), ISAllGather() 5147 5148 @*/ 5149 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5150 { 5151 PetscErrorCode ierr; 5152 5153 PetscFunctionBegin; 5154 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5155 PetscValidType(mat,1); 5156 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5157 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5158 PetscValidPointer(B,4); 5159 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5160 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5161 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5162 MatCheckPreallocated(mat,1); 5163 5164 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5165 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5166 PetscFunctionReturn(0); 5167 } 5168 5169 /*@ 5170 MatEqual - Compares two matrices. 5171 5172 Collective on Mat 5173 5174 Input Parameters: 5175 + A - the first matrix 5176 - B - the second matrix 5177 5178 Output Parameter: 5179 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5180 5181 Level: intermediate 5182 5183 @*/ 5184 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5185 { 5186 PetscErrorCode ierr; 5187 5188 PetscFunctionBegin; 5189 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5190 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5191 PetscValidType(A,1); 5192 PetscValidType(B,2); 5193 PetscValidBoolPointer(flg,3); 5194 PetscCheckSameComm(A,1,B,2); 5195 MatCheckPreallocated(B,2); 5196 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5197 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5198 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); 5199 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5200 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5201 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); 5202 MatCheckPreallocated(A,1); 5203 5204 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5205 PetscFunctionReturn(0); 5206 } 5207 5208 /*@ 5209 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5210 matrices that are stored as vectors. Either of the two scaling 5211 matrices can be NULL. 5212 5213 Collective on Mat 5214 5215 Input Parameters: 5216 + mat - the matrix to be scaled 5217 . l - the left scaling vector (or NULL) 5218 - r - the right scaling vector (or NULL) 5219 5220 Notes: 5221 MatDiagonalScale() computes A = LAR, where 5222 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5223 The L scales the rows of the matrix, the R scales the columns of the matrix. 5224 5225 Level: intermediate 5226 5227 5228 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5229 @*/ 5230 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5231 { 5232 PetscErrorCode ierr; 5233 5234 PetscFunctionBegin; 5235 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5236 PetscValidType(mat,1); 5237 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5238 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5239 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5240 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5241 MatCheckPreallocated(mat,1); 5242 if (!l && !r) PetscFunctionReturn(0); 5243 5244 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5245 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5246 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5247 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5248 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5249 PetscFunctionReturn(0); 5250 } 5251 5252 /*@ 5253 MatScale - Scales all elements of a matrix by a given number. 5254 5255 Logically Collective on Mat 5256 5257 Input Parameters: 5258 + mat - the matrix to be scaled 5259 - a - the scaling value 5260 5261 Output Parameter: 5262 . mat - the scaled matrix 5263 5264 Level: intermediate 5265 5266 .seealso: MatDiagonalScale() 5267 @*/ 5268 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5269 { 5270 PetscErrorCode ierr; 5271 5272 PetscFunctionBegin; 5273 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5274 PetscValidType(mat,1); 5275 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5276 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5277 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5278 PetscValidLogicalCollectiveScalar(mat,a,2); 5279 MatCheckPreallocated(mat,1); 5280 5281 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5282 if (a != (PetscScalar)1.0) { 5283 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5284 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5285 } 5286 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5287 PetscFunctionReturn(0); 5288 } 5289 5290 /*@ 5291 MatNorm - Calculates various norms of a matrix. 5292 5293 Collective on Mat 5294 5295 Input Parameters: 5296 + mat - the matrix 5297 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5298 5299 Output Parameters: 5300 . nrm - the resulting norm 5301 5302 Level: intermediate 5303 5304 @*/ 5305 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5306 { 5307 PetscErrorCode ierr; 5308 5309 PetscFunctionBegin; 5310 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5311 PetscValidType(mat,1); 5312 PetscValidScalarPointer(nrm,3); 5313 5314 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5315 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5316 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5317 MatCheckPreallocated(mat,1); 5318 5319 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5320 PetscFunctionReturn(0); 5321 } 5322 5323 /* 5324 This variable is used to prevent counting of MatAssemblyBegin() that 5325 are called from within a MatAssemblyEnd(). 5326 */ 5327 static PetscInt MatAssemblyEnd_InUse = 0; 5328 /*@ 5329 MatAssemblyBegin - Begins assembling the matrix. This routine should 5330 be called after completing all calls to MatSetValues(). 5331 5332 Collective on Mat 5333 5334 Input Parameters: 5335 + mat - the matrix 5336 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5337 5338 Notes: 5339 MatSetValues() generally caches the values. The matrix is ready to 5340 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5341 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5342 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5343 using the matrix. 5344 5345 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5346 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 5347 a global collective operation requring all processes that share the matrix. 5348 5349 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5350 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5351 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5352 5353 Level: beginner 5354 5355 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5356 @*/ 5357 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5358 { 5359 PetscErrorCode ierr; 5360 5361 PetscFunctionBegin; 5362 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5363 PetscValidType(mat,1); 5364 MatCheckPreallocated(mat,1); 5365 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5366 if (mat->assembled) { 5367 mat->was_assembled = PETSC_TRUE; 5368 mat->assembled = PETSC_FALSE; 5369 } 5370 5371 if (!MatAssemblyEnd_InUse) { 5372 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5373 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5374 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5375 } else if (mat->ops->assemblybegin) { 5376 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5377 } 5378 PetscFunctionReturn(0); 5379 } 5380 5381 /*@ 5382 MatAssembled - Indicates if a matrix has been assembled and is ready for 5383 use; for example, in matrix-vector product. 5384 5385 Not Collective 5386 5387 Input Parameter: 5388 . mat - the matrix 5389 5390 Output Parameter: 5391 . assembled - PETSC_TRUE or PETSC_FALSE 5392 5393 Level: advanced 5394 5395 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5396 @*/ 5397 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5398 { 5399 PetscFunctionBegin; 5400 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5401 PetscValidPointer(assembled,2); 5402 *assembled = mat->assembled; 5403 PetscFunctionReturn(0); 5404 } 5405 5406 /*@ 5407 MatAssemblyEnd - Completes assembling the matrix. This routine should 5408 be called after MatAssemblyBegin(). 5409 5410 Collective on Mat 5411 5412 Input Parameters: 5413 + mat - the matrix 5414 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5415 5416 Options Database Keys: 5417 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5418 . -mat_view ::ascii_info_detail - Prints more detailed info 5419 . -mat_view - Prints matrix in ASCII format 5420 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5421 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5422 . -display <name> - Sets display name (default is host) 5423 . -draw_pause <sec> - Sets number of seconds to pause after display 5424 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5425 . -viewer_socket_machine <machine> - Machine to use for socket 5426 . -viewer_socket_port <port> - Port number to use for socket 5427 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5428 5429 Notes: 5430 MatSetValues() generally caches the values. The matrix is ready to 5431 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5432 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5433 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5434 using the matrix. 5435 5436 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5437 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5438 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5439 5440 Level: beginner 5441 5442 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5443 @*/ 5444 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5445 { 5446 PetscErrorCode ierr; 5447 static PetscInt inassm = 0; 5448 PetscBool flg = PETSC_FALSE; 5449 5450 PetscFunctionBegin; 5451 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5452 PetscValidType(mat,1); 5453 5454 inassm++; 5455 MatAssemblyEnd_InUse++; 5456 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5457 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5458 if (mat->ops->assemblyend) { 5459 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5460 } 5461 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5462 } else if (mat->ops->assemblyend) { 5463 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5464 } 5465 5466 /* Flush assembly is not a true assembly */ 5467 if (type != MAT_FLUSH_ASSEMBLY) { 5468 mat->num_ass++; 5469 mat->assembled = PETSC_TRUE; 5470 mat->ass_nonzerostate = mat->nonzerostate; 5471 } 5472 5473 mat->insertmode = NOT_SET_VALUES; 5474 MatAssemblyEnd_InUse--; 5475 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5476 if (!mat->symmetric_eternal) { 5477 mat->symmetric_set = PETSC_FALSE; 5478 mat->hermitian_set = PETSC_FALSE; 5479 mat->structurally_symmetric_set = PETSC_FALSE; 5480 } 5481 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5482 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5483 5484 if (mat->checksymmetryonassembly) { 5485 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5486 if (flg) { 5487 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5488 } else { 5489 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5490 } 5491 } 5492 if (mat->nullsp && mat->checknullspaceonassembly) { 5493 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5494 } 5495 } 5496 inassm--; 5497 PetscFunctionReturn(0); 5498 } 5499 5500 /*@ 5501 MatSetOption - Sets a parameter option for a matrix. Some options 5502 may be specific to certain storage formats. Some options 5503 determine how values will be inserted (or added). Sorted, 5504 row-oriented input will generally assemble the fastest. The default 5505 is row-oriented. 5506 5507 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5508 5509 Input Parameters: 5510 + mat - the matrix 5511 . option - the option, one of those listed below (and possibly others), 5512 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5513 5514 Options Describing Matrix Structure: 5515 + MAT_SPD - symmetric positive definite 5516 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5517 . MAT_HERMITIAN - transpose is the complex conjugation 5518 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5519 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5520 you set to be kept with all future use of the matrix 5521 including after MatAssemblyBegin/End() which could 5522 potentially change the symmetry structure, i.e. you 5523 KNOW the matrix will ALWAYS have the property you set. 5524 Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian; 5525 the relevant flags must be set independently. 5526 5527 5528 Options For Use with MatSetValues(): 5529 Insert a logically dense subblock, which can be 5530 . MAT_ROW_ORIENTED - row-oriented (default) 5531 5532 Note these options reflect the data you pass in with MatSetValues(); it has 5533 nothing to do with how the data is stored internally in the matrix 5534 data structure. 5535 5536 When (re)assembling a matrix, we can restrict the input for 5537 efficiency/debugging purposes. These options include: 5538 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5539 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5540 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5541 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5542 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5543 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5544 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5545 performance for very large process counts. 5546 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5547 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5548 functions, instead sending only neighbor messages. 5549 5550 Notes: 5551 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5552 5553 Some options are relevant only for particular matrix types and 5554 are thus ignored by others. Other options are not supported by 5555 certain matrix types and will generate an error message if set. 5556 5557 If using a Fortran 77 module to compute a matrix, one may need to 5558 use the column-oriented option (or convert to the row-oriented 5559 format). 5560 5561 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5562 that would generate a new entry in the nonzero structure is instead 5563 ignored. Thus, if memory has not alredy been allocated for this particular 5564 data, then the insertion is ignored. For dense matrices, in which 5565 the entire array is allocated, no entries are ever ignored. 5566 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5567 5568 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5569 that would generate a new entry in the nonzero structure instead produces 5570 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 5571 5572 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5573 that would generate a new entry that has not been preallocated will 5574 instead produce an error. (Currently supported for AIJ and BAIJ formats 5575 only.) This is a useful flag when debugging matrix memory preallocation. 5576 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5577 5578 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5579 other processors should be dropped, rather than stashed. 5580 This is useful if you know that the "owning" processor is also 5581 always generating the correct matrix entries, so that PETSc need 5582 not transfer duplicate entries generated on another processor. 5583 5584 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5585 searches during matrix assembly. When this flag is set, the hash table 5586 is created during the first Matrix Assembly. This hash table is 5587 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5588 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5589 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5590 supported by MATMPIBAIJ format only. 5591 5592 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5593 are kept in the nonzero structure 5594 5595 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5596 a zero location in the matrix 5597 5598 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5599 5600 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5601 zero row routines and thus improves performance for very large process counts. 5602 5603 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5604 part of the matrix (since they should match the upper triangular part). 5605 5606 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5607 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5608 with finite difference schemes with non-periodic boundary conditions. 5609 5610 Level: intermediate 5611 5612 .seealso: MatOption, Mat 5613 5614 @*/ 5615 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5616 { 5617 PetscErrorCode ierr; 5618 5619 PetscFunctionBegin; 5620 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5621 if (op > 0) { 5622 PetscValidLogicalCollectiveEnum(mat,op,2); 5623 PetscValidLogicalCollectiveBool(mat,flg,3); 5624 } 5625 5626 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); 5627 5628 switch (op) { 5629 case MAT_FORCE_DIAGONAL_ENTRIES: 5630 mat->force_diagonals = flg; 5631 PetscFunctionReturn(0); 5632 case MAT_NO_OFF_PROC_ENTRIES: 5633 mat->nooffprocentries = flg; 5634 PetscFunctionReturn(0); 5635 case MAT_SUBSET_OFF_PROC_ENTRIES: 5636 mat->assembly_subset = flg; 5637 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5638 #if !defined(PETSC_HAVE_MPIUNI) 5639 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5640 #endif 5641 mat->stash.first_assembly_done = PETSC_FALSE; 5642 } 5643 PetscFunctionReturn(0); 5644 case MAT_NO_OFF_PROC_ZERO_ROWS: 5645 mat->nooffproczerorows = flg; 5646 PetscFunctionReturn(0); 5647 case MAT_SPD: 5648 mat->spd_set = PETSC_TRUE; 5649 mat->spd = flg; 5650 if (flg) { 5651 mat->symmetric = PETSC_TRUE; 5652 mat->structurally_symmetric = PETSC_TRUE; 5653 mat->symmetric_set = PETSC_TRUE; 5654 mat->structurally_symmetric_set = PETSC_TRUE; 5655 } 5656 break; 5657 case MAT_SYMMETRIC: 5658 mat->symmetric = flg; 5659 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5660 mat->symmetric_set = PETSC_TRUE; 5661 mat->structurally_symmetric_set = flg; 5662 #if !defined(PETSC_USE_COMPLEX) 5663 mat->hermitian = flg; 5664 mat->hermitian_set = PETSC_TRUE; 5665 #endif 5666 break; 5667 case MAT_HERMITIAN: 5668 mat->hermitian = flg; 5669 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5670 mat->hermitian_set = PETSC_TRUE; 5671 mat->structurally_symmetric_set = flg; 5672 #if !defined(PETSC_USE_COMPLEX) 5673 mat->symmetric = flg; 5674 mat->symmetric_set = PETSC_TRUE; 5675 #endif 5676 break; 5677 case MAT_STRUCTURALLY_SYMMETRIC: 5678 mat->structurally_symmetric = flg; 5679 mat->structurally_symmetric_set = PETSC_TRUE; 5680 break; 5681 case MAT_SYMMETRY_ETERNAL: 5682 mat->symmetric_eternal = flg; 5683 break; 5684 case MAT_STRUCTURE_ONLY: 5685 mat->structure_only = flg; 5686 break; 5687 case MAT_SORTED_FULL: 5688 mat->sortedfull = flg; 5689 break; 5690 default: 5691 break; 5692 } 5693 if (mat->ops->setoption) { 5694 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5695 } 5696 PetscFunctionReturn(0); 5697 } 5698 5699 /*@ 5700 MatGetOption - Gets a parameter option that has been set for a matrix. 5701 5702 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5703 5704 Input Parameters: 5705 + mat - the matrix 5706 - option - the option, this only responds to certain options, check the code for which ones 5707 5708 Output Parameter: 5709 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5710 5711 Notes: 5712 Can only be called after MatSetSizes() and MatSetType() have been set. 5713 5714 Level: intermediate 5715 5716 .seealso: MatOption, MatSetOption() 5717 5718 @*/ 5719 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5720 { 5721 PetscFunctionBegin; 5722 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5723 PetscValidType(mat,1); 5724 5725 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); 5726 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()"); 5727 5728 switch (op) { 5729 case MAT_NO_OFF_PROC_ENTRIES: 5730 *flg = mat->nooffprocentries; 5731 break; 5732 case MAT_NO_OFF_PROC_ZERO_ROWS: 5733 *flg = mat->nooffproczerorows; 5734 break; 5735 case MAT_SYMMETRIC: 5736 *flg = mat->symmetric; 5737 break; 5738 case MAT_HERMITIAN: 5739 *flg = mat->hermitian; 5740 break; 5741 case MAT_STRUCTURALLY_SYMMETRIC: 5742 *flg = mat->structurally_symmetric; 5743 break; 5744 case MAT_SYMMETRY_ETERNAL: 5745 *flg = mat->symmetric_eternal; 5746 break; 5747 case MAT_SPD: 5748 *flg = mat->spd; 5749 break; 5750 default: 5751 break; 5752 } 5753 PetscFunctionReturn(0); 5754 } 5755 5756 /*@ 5757 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5758 this routine retains the old nonzero structure. 5759 5760 Logically Collective on Mat 5761 5762 Input Parameters: 5763 . mat - the matrix 5764 5765 Level: intermediate 5766 5767 Notes: 5768 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. 5769 See the Performance chapter of the users manual for information on preallocating matrices. 5770 5771 .seealso: MatZeroRows() 5772 @*/ 5773 PetscErrorCode MatZeroEntries(Mat mat) 5774 { 5775 PetscErrorCode ierr; 5776 5777 PetscFunctionBegin; 5778 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5779 PetscValidType(mat,1); 5780 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5781 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"); 5782 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5783 MatCheckPreallocated(mat,1); 5784 5785 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5786 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5787 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5788 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5789 PetscFunctionReturn(0); 5790 } 5791 5792 /*@ 5793 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5794 of a set of rows and columns of a matrix. 5795 5796 Collective on Mat 5797 5798 Input Parameters: 5799 + mat - the matrix 5800 . numRows - the number of rows to remove 5801 . rows - the global row indices 5802 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5803 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5804 - b - optional vector of right hand side, that will be adjusted by provided solution 5805 5806 Notes: 5807 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5808 5809 The user can set a value in the diagonal entry (or for the AIJ and 5810 row formats can optionally remove the main diagonal entry from the 5811 nonzero structure as well, by passing 0.0 as the final argument). 5812 5813 For the parallel case, all processes that share the matrix (i.e., 5814 those in the communicator used for matrix creation) MUST call this 5815 routine, regardless of whether any rows being zeroed are owned by 5816 them. 5817 5818 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5819 list only rows local to itself). 5820 5821 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5822 5823 Level: intermediate 5824 5825 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5826 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5827 @*/ 5828 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5829 { 5830 PetscErrorCode ierr; 5831 5832 PetscFunctionBegin; 5833 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5834 PetscValidType(mat,1); 5835 if (numRows) PetscValidIntPointer(rows,3); 5836 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5837 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5838 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5839 MatCheckPreallocated(mat,1); 5840 5841 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5842 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5843 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5844 PetscFunctionReturn(0); 5845 } 5846 5847 /*@ 5848 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5849 of a set of rows and columns of a matrix. 5850 5851 Collective on Mat 5852 5853 Input Parameters: 5854 + mat - the matrix 5855 . is - the rows to zero 5856 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5857 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5858 - b - optional vector of right hand side, that will be adjusted by provided solution 5859 5860 Notes: 5861 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5862 5863 The user can set a value in the diagonal entry (or for the AIJ and 5864 row formats can optionally remove the main diagonal entry from the 5865 nonzero structure as well, by passing 0.0 as the final argument). 5866 5867 For the parallel case, all processes that share the matrix (i.e., 5868 those in the communicator used for matrix creation) MUST call this 5869 routine, regardless of whether any rows being zeroed are owned by 5870 them. 5871 5872 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5873 list only rows local to itself). 5874 5875 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5876 5877 Level: intermediate 5878 5879 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5880 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5881 @*/ 5882 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5883 { 5884 PetscErrorCode ierr; 5885 PetscInt numRows; 5886 const PetscInt *rows; 5887 5888 PetscFunctionBegin; 5889 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5890 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5891 PetscValidType(mat,1); 5892 PetscValidType(is,2); 5893 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5894 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5895 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5896 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5897 PetscFunctionReturn(0); 5898 } 5899 5900 /*@ 5901 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5902 of a set of rows of a matrix. 5903 5904 Collective on Mat 5905 5906 Input Parameters: 5907 + mat - the matrix 5908 . numRows - the number of rows to remove 5909 . rows - the global row indices 5910 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5911 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5912 - b - optional vector of right hand side, that will be adjusted by provided solution 5913 5914 Notes: 5915 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5916 but does not release memory. For the dense and block diagonal 5917 formats this does not alter the nonzero structure. 5918 5919 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5920 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5921 merely zeroed. 5922 5923 The user can set a value in the diagonal entry (or for the AIJ and 5924 row formats can optionally remove the main diagonal entry from the 5925 nonzero structure as well, by passing 0.0 as the final argument). 5926 5927 For the parallel case, all processes that share the matrix (i.e., 5928 those in the communicator used for matrix creation) MUST call this 5929 routine, regardless of whether any rows being zeroed are owned by 5930 them. 5931 5932 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5933 list only rows local to itself). 5934 5935 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5936 owns that are to be zeroed. This saves a global synchronization in the implementation. 5937 5938 Level: intermediate 5939 5940 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5941 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5942 @*/ 5943 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5944 { 5945 PetscErrorCode ierr; 5946 5947 PetscFunctionBegin; 5948 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5949 PetscValidType(mat,1); 5950 if (numRows) PetscValidIntPointer(rows,3); 5951 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5952 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5953 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5954 MatCheckPreallocated(mat,1); 5955 5956 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5957 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5958 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5959 PetscFunctionReturn(0); 5960 } 5961 5962 /*@ 5963 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5964 of a set of rows of a matrix. 5965 5966 Collective on Mat 5967 5968 Input Parameters: 5969 + mat - the matrix 5970 . is - index set of rows to remove 5971 . diag - value put in all diagonals of eliminated rows 5972 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5973 - b - optional vector of right hand side, that will be adjusted by provided solution 5974 5975 Notes: 5976 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5977 but does not release memory. For the dense and block diagonal 5978 formats this does not alter the nonzero structure. 5979 5980 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5981 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5982 merely zeroed. 5983 5984 The user can set a value in the diagonal entry (or for the AIJ and 5985 row formats can optionally remove the main diagonal entry from the 5986 nonzero structure as well, by passing 0.0 as the final argument). 5987 5988 For the parallel case, all processes that share the matrix (i.e., 5989 those in the communicator used for matrix creation) MUST call this 5990 routine, regardless of whether any rows being zeroed are owned by 5991 them. 5992 5993 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5994 list only rows local to itself). 5995 5996 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5997 owns that are to be zeroed. This saves a global synchronization in the implementation. 5998 5999 Level: intermediate 6000 6001 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6002 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6003 @*/ 6004 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6005 { 6006 PetscInt numRows; 6007 const PetscInt *rows; 6008 PetscErrorCode ierr; 6009 6010 PetscFunctionBegin; 6011 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6012 PetscValidType(mat,1); 6013 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6014 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6015 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6016 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6017 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6018 PetscFunctionReturn(0); 6019 } 6020 6021 /*@ 6022 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6023 of a set of rows of a matrix. These rows must be local to the process. 6024 6025 Collective on Mat 6026 6027 Input Parameters: 6028 + mat - the matrix 6029 . numRows - the number of rows to remove 6030 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6031 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6032 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6033 - b - optional vector of right hand side, that will be adjusted by provided solution 6034 6035 Notes: 6036 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6037 but does not release memory. For the dense and block diagonal 6038 formats this does not alter the nonzero structure. 6039 6040 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6041 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6042 merely zeroed. 6043 6044 The user can set a value in the diagonal entry (or for the AIJ and 6045 row formats can optionally remove the main diagonal entry from the 6046 nonzero structure as well, by passing 0.0 as the final argument). 6047 6048 For the parallel case, all processes that share the matrix (i.e., 6049 those in the communicator used for matrix creation) MUST call this 6050 routine, regardless of whether any rows being zeroed are owned by 6051 them. 6052 6053 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6054 list only rows local to itself). 6055 6056 The grid coordinates are across the entire grid, not just the local portion 6057 6058 In Fortran idxm and idxn should be declared as 6059 $ MatStencil idxm(4,m) 6060 and the values inserted using 6061 $ idxm(MatStencil_i,1) = i 6062 $ idxm(MatStencil_j,1) = j 6063 $ idxm(MatStencil_k,1) = k 6064 $ idxm(MatStencil_c,1) = c 6065 etc 6066 6067 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6068 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6069 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6070 DM_BOUNDARY_PERIODIC boundary type. 6071 6072 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 6073 a single value per point) you can skip filling those indices. 6074 6075 Level: intermediate 6076 6077 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6078 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6079 @*/ 6080 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6081 { 6082 PetscInt dim = mat->stencil.dim; 6083 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6084 PetscInt *dims = mat->stencil.dims+1; 6085 PetscInt *starts = mat->stencil.starts; 6086 PetscInt *dxm = (PetscInt*) rows; 6087 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6088 PetscErrorCode ierr; 6089 6090 PetscFunctionBegin; 6091 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6092 PetscValidType(mat,1); 6093 if (numRows) PetscValidIntPointer(rows,3); 6094 6095 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6096 for (i = 0; i < numRows; ++i) { 6097 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6098 for (j = 0; j < 3-sdim; ++j) dxm++; 6099 /* Local index in X dir */ 6100 tmp = *dxm++ - starts[0]; 6101 /* Loop over remaining dimensions */ 6102 for (j = 0; j < dim-1; ++j) { 6103 /* If nonlocal, set index to be negative */ 6104 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6105 /* Update local index */ 6106 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6107 } 6108 /* Skip component slot if necessary */ 6109 if (mat->stencil.noc) dxm++; 6110 /* Local row number */ 6111 if (tmp >= 0) { 6112 jdxm[numNewRows++] = tmp; 6113 } 6114 } 6115 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6116 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6117 PetscFunctionReturn(0); 6118 } 6119 6120 /*@ 6121 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6122 of a set of rows and columns of a matrix. 6123 6124 Collective on Mat 6125 6126 Input Parameters: 6127 + mat - the matrix 6128 . numRows - the number of rows/columns to remove 6129 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6130 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6131 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6132 - b - optional vector of right hand side, that will be adjusted by provided solution 6133 6134 Notes: 6135 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6136 but does not release memory. For the dense and block diagonal 6137 formats this does not alter the nonzero structure. 6138 6139 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6140 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6141 merely zeroed. 6142 6143 The user can set a value in the diagonal entry (or for the AIJ and 6144 row formats can optionally remove the main diagonal entry from the 6145 nonzero structure as well, by passing 0.0 as the final argument). 6146 6147 For the parallel case, all processes that share the matrix (i.e., 6148 those in the communicator used for matrix creation) MUST call this 6149 routine, regardless of whether any rows being zeroed are owned by 6150 them. 6151 6152 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6153 list only rows local to itself, but the row/column numbers are given in local numbering). 6154 6155 The grid coordinates are across the entire grid, not just the local portion 6156 6157 In Fortran idxm and idxn should be declared as 6158 $ MatStencil idxm(4,m) 6159 and the values inserted using 6160 $ idxm(MatStencil_i,1) = i 6161 $ idxm(MatStencil_j,1) = j 6162 $ idxm(MatStencil_k,1) = k 6163 $ idxm(MatStencil_c,1) = c 6164 etc 6165 6166 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6167 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6168 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6169 DM_BOUNDARY_PERIODIC boundary type. 6170 6171 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 6172 a single value per point) you can skip filling those indices. 6173 6174 Level: intermediate 6175 6176 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6177 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6178 @*/ 6179 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6180 { 6181 PetscInt dim = mat->stencil.dim; 6182 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6183 PetscInt *dims = mat->stencil.dims+1; 6184 PetscInt *starts = mat->stencil.starts; 6185 PetscInt *dxm = (PetscInt*) rows; 6186 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6187 PetscErrorCode ierr; 6188 6189 PetscFunctionBegin; 6190 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6191 PetscValidType(mat,1); 6192 if (numRows) PetscValidIntPointer(rows,3); 6193 6194 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6195 for (i = 0; i < numRows; ++i) { 6196 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6197 for (j = 0; j < 3-sdim; ++j) dxm++; 6198 /* Local index in X dir */ 6199 tmp = *dxm++ - starts[0]; 6200 /* Loop over remaining dimensions */ 6201 for (j = 0; j < dim-1; ++j) { 6202 /* If nonlocal, set index to be negative */ 6203 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6204 /* Update local index */ 6205 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6206 } 6207 /* Skip component slot if necessary */ 6208 if (mat->stencil.noc) dxm++; 6209 /* Local row number */ 6210 if (tmp >= 0) { 6211 jdxm[numNewRows++] = tmp; 6212 } 6213 } 6214 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6215 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6216 PetscFunctionReturn(0); 6217 } 6218 6219 /*@C 6220 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6221 of a set of rows of a matrix; using local numbering of rows. 6222 6223 Collective on Mat 6224 6225 Input Parameters: 6226 + mat - the matrix 6227 . numRows - the number of rows to remove 6228 . rows - the global row indices 6229 . diag - value put in all diagonals of eliminated rows 6230 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6231 - b - optional vector of right hand side, that will be adjusted by provided solution 6232 6233 Notes: 6234 Before calling MatZeroRowsLocal(), the user must first set the 6235 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6236 6237 For the AIJ matrix formats this removes the old nonzero structure, 6238 but does not release memory. For the dense and block diagonal 6239 formats this does not alter the nonzero structure. 6240 6241 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6242 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6243 merely zeroed. 6244 6245 The user can set a value in the diagonal entry (or for the AIJ and 6246 row formats can optionally remove the main diagonal entry from the 6247 nonzero structure as well, by passing 0.0 as the final argument). 6248 6249 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6250 owns that are to be zeroed. This saves a global synchronization in the implementation. 6251 6252 Level: intermediate 6253 6254 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6255 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6256 @*/ 6257 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6258 { 6259 PetscErrorCode ierr; 6260 6261 PetscFunctionBegin; 6262 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6263 PetscValidType(mat,1); 6264 if (numRows) PetscValidIntPointer(rows,3); 6265 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6266 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6267 MatCheckPreallocated(mat,1); 6268 6269 if (mat->ops->zerorowslocal) { 6270 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6271 } else { 6272 IS is, newis; 6273 const PetscInt *newRows; 6274 6275 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6276 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6277 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6278 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6279 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6280 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6281 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6282 ierr = ISDestroy(&is);CHKERRQ(ierr); 6283 } 6284 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6285 PetscFunctionReturn(0); 6286 } 6287 6288 /*@ 6289 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6290 of a set of rows of a matrix; using local numbering of rows. 6291 6292 Collective on Mat 6293 6294 Input Parameters: 6295 + mat - the matrix 6296 . is - index set of rows to remove 6297 . diag - value put in all diagonals of eliminated rows 6298 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6299 - b - optional vector of right hand side, that will be adjusted by provided solution 6300 6301 Notes: 6302 Before calling MatZeroRowsLocalIS(), the user must first set the 6303 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6304 6305 For the AIJ matrix formats this removes the old nonzero structure, 6306 but does not release memory. For the dense and block diagonal 6307 formats this does not alter the nonzero structure. 6308 6309 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6310 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6311 merely zeroed. 6312 6313 The user can set a value in the diagonal entry (or for the AIJ and 6314 row formats can optionally remove the main diagonal entry from the 6315 nonzero structure as well, by passing 0.0 as the final argument). 6316 6317 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6318 owns that are to be zeroed. This saves a global synchronization in the implementation. 6319 6320 Level: intermediate 6321 6322 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6323 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6324 @*/ 6325 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6326 { 6327 PetscErrorCode ierr; 6328 PetscInt numRows; 6329 const PetscInt *rows; 6330 6331 PetscFunctionBegin; 6332 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6333 PetscValidType(mat,1); 6334 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6335 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6336 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6337 MatCheckPreallocated(mat,1); 6338 6339 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6340 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6341 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6342 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6343 PetscFunctionReturn(0); 6344 } 6345 6346 /*@ 6347 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6348 of a set of rows and columns of a matrix; using local numbering of rows. 6349 6350 Collective on Mat 6351 6352 Input Parameters: 6353 + mat - the matrix 6354 . numRows - the number of rows to remove 6355 . rows - the global row indices 6356 . diag - value put in all diagonals of eliminated rows 6357 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6358 - b - optional vector of right hand side, that will be adjusted by provided solution 6359 6360 Notes: 6361 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6362 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6363 6364 The user can set a value in the diagonal entry (or for the AIJ and 6365 row formats can optionally remove the main diagonal entry from the 6366 nonzero structure as well, by passing 0.0 as the final argument). 6367 6368 Level: intermediate 6369 6370 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6371 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6372 @*/ 6373 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6374 { 6375 PetscErrorCode ierr; 6376 IS is, newis; 6377 const PetscInt *newRows; 6378 6379 PetscFunctionBegin; 6380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6381 PetscValidType(mat,1); 6382 if (numRows) PetscValidIntPointer(rows,3); 6383 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6384 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6385 MatCheckPreallocated(mat,1); 6386 6387 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6388 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6389 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6390 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6391 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6392 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6393 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6394 ierr = ISDestroy(&is);CHKERRQ(ierr); 6395 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6396 PetscFunctionReturn(0); 6397 } 6398 6399 /*@ 6400 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6401 of a set of rows and columns of a matrix; using local numbering of rows. 6402 6403 Collective on Mat 6404 6405 Input Parameters: 6406 + mat - the matrix 6407 . is - index set of rows to remove 6408 . diag - value put in all diagonals of eliminated rows 6409 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6410 - b - optional vector of right hand side, that will be adjusted by provided solution 6411 6412 Notes: 6413 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6414 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6415 6416 The user can set a value in the diagonal entry (or for the AIJ and 6417 row formats can optionally remove the main diagonal entry from the 6418 nonzero structure as well, by passing 0.0 as the final argument). 6419 6420 Level: intermediate 6421 6422 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6423 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6424 @*/ 6425 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6426 { 6427 PetscErrorCode ierr; 6428 PetscInt numRows; 6429 const PetscInt *rows; 6430 6431 PetscFunctionBegin; 6432 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6433 PetscValidType(mat,1); 6434 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6435 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6436 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6437 MatCheckPreallocated(mat,1); 6438 6439 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6440 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6441 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6442 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6443 PetscFunctionReturn(0); 6444 } 6445 6446 /*@C 6447 MatGetSize - Returns the numbers of rows and columns in a matrix. 6448 6449 Not Collective 6450 6451 Input Parameter: 6452 . mat - the matrix 6453 6454 Output Parameters: 6455 + m - the number of global rows 6456 - n - the number of global columns 6457 6458 Note: both output parameters can be NULL on input. 6459 6460 Level: beginner 6461 6462 .seealso: MatGetLocalSize() 6463 @*/ 6464 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6465 { 6466 PetscFunctionBegin; 6467 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6468 if (m) *m = mat->rmap->N; 6469 if (n) *n = mat->cmap->N; 6470 PetscFunctionReturn(0); 6471 } 6472 6473 /*@C 6474 MatGetLocalSize - Returns the number of local rows and local columns 6475 of a matrix, that is the local size of the left and right vectors as returned by MatCreateVecs(). 6476 6477 Not Collective 6478 6479 Input Parameters: 6480 . mat - the matrix 6481 6482 Output Parameters: 6483 + m - the number of local rows 6484 - n - the number of local columns 6485 6486 Note: both output parameters can be NULL on input. 6487 6488 Level: beginner 6489 6490 .seealso: MatGetSize() 6491 @*/ 6492 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6493 { 6494 PetscFunctionBegin; 6495 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6496 if (m) PetscValidIntPointer(m,2); 6497 if (n) PetscValidIntPointer(n,3); 6498 if (m) *m = mat->rmap->n; 6499 if (n) *n = mat->cmap->n; 6500 PetscFunctionReturn(0); 6501 } 6502 6503 /*@C 6504 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6505 this processor. (The columns of the "diagonal block") 6506 6507 Not Collective, unless matrix has not been allocated, then collective on Mat 6508 6509 Input Parameters: 6510 . mat - the matrix 6511 6512 Output Parameters: 6513 + m - the global index of the first local column 6514 - n - one more than the global index of the last local column 6515 6516 Notes: 6517 both output parameters can be NULL on input. 6518 6519 Level: developer 6520 6521 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6522 6523 @*/ 6524 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6525 { 6526 PetscFunctionBegin; 6527 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6528 PetscValidType(mat,1); 6529 if (m) PetscValidIntPointer(m,2); 6530 if (n) PetscValidIntPointer(n,3); 6531 MatCheckPreallocated(mat,1); 6532 if (m) *m = mat->cmap->rstart; 6533 if (n) *n = mat->cmap->rend; 6534 PetscFunctionReturn(0); 6535 } 6536 6537 /*@C 6538 MatGetOwnershipRange - Returns the range of matrix rows owned by 6539 this processor, assuming that the matrix is laid out with the first 6540 n1 rows on the first processor, the next n2 rows on the second, etc. 6541 For certain parallel layouts this range may not be well defined. 6542 6543 Not Collective 6544 6545 Input Parameters: 6546 . mat - the matrix 6547 6548 Output Parameters: 6549 + m - the global index of the first local row 6550 - n - one more than the global index of the last local row 6551 6552 Note: Both output parameters can be NULL on input. 6553 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6554 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6555 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6556 6557 Level: beginner 6558 6559 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6560 6561 @*/ 6562 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6563 { 6564 PetscFunctionBegin; 6565 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6566 PetscValidType(mat,1); 6567 if (m) PetscValidIntPointer(m,2); 6568 if (n) PetscValidIntPointer(n,3); 6569 MatCheckPreallocated(mat,1); 6570 if (m) *m = mat->rmap->rstart; 6571 if (n) *n = mat->rmap->rend; 6572 PetscFunctionReturn(0); 6573 } 6574 6575 /*@C 6576 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6577 each process 6578 6579 Not Collective, unless matrix has not been allocated, then collective on Mat 6580 6581 Input Parameters: 6582 . mat - the matrix 6583 6584 Output Parameters: 6585 . ranges - start of each processors portion plus one more than the total length at the end 6586 6587 Level: beginner 6588 6589 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6590 6591 @*/ 6592 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6593 { 6594 PetscErrorCode ierr; 6595 6596 PetscFunctionBegin; 6597 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6598 PetscValidType(mat,1); 6599 MatCheckPreallocated(mat,1); 6600 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6601 PetscFunctionReturn(0); 6602 } 6603 6604 /*@C 6605 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6606 this processor. (The columns of the "diagonal blocks" for each process) 6607 6608 Not Collective, unless matrix has not been allocated, then collective on Mat 6609 6610 Input Parameters: 6611 . mat - the matrix 6612 6613 Output Parameters: 6614 . ranges - start of each processors portion plus one more then the total length at the end 6615 6616 Level: beginner 6617 6618 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6619 6620 @*/ 6621 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6622 { 6623 PetscErrorCode ierr; 6624 6625 PetscFunctionBegin; 6626 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6627 PetscValidType(mat,1); 6628 MatCheckPreallocated(mat,1); 6629 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6630 PetscFunctionReturn(0); 6631 } 6632 6633 /*@C 6634 MatGetOwnershipIS - Get row and column ownership as index sets 6635 6636 Not Collective 6637 6638 Input Arguments: 6639 . A - matrix of type Elemental or ScaLAPACK 6640 6641 Output Arguments: 6642 + rows - rows in which this process owns elements 6643 - cols - columns in which this process owns elements 6644 6645 Level: intermediate 6646 6647 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6648 @*/ 6649 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6650 { 6651 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6652 6653 PetscFunctionBegin; 6654 MatCheckPreallocated(A,1); 6655 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6656 if (f) { 6657 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6658 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6659 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6660 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6661 } 6662 PetscFunctionReturn(0); 6663 } 6664 6665 /*@C 6666 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6667 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6668 to complete the factorization. 6669 6670 Collective on Mat 6671 6672 Input Parameters: 6673 + mat - the matrix 6674 . row - row permutation 6675 . column - column permutation 6676 - info - structure containing 6677 $ levels - number of levels of fill. 6678 $ expected fill - as ratio of original fill. 6679 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6680 missing diagonal entries) 6681 6682 Output Parameters: 6683 . fact - new matrix that has been symbolically factored 6684 6685 Notes: 6686 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6687 6688 Most users should employ the simplified KSP interface for linear solvers 6689 instead of working directly with matrix algebra routines such as this. 6690 See, e.g., KSPCreate(). 6691 6692 Level: developer 6693 6694 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6695 MatGetOrdering(), MatFactorInfo 6696 6697 Note: this uses the definition of level of fill as in Y. Saad, 2003 6698 6699 Developer Note: fortran interface is not autogenerated as the f90 6700 interface defintion cannot be generated correctly [due to MatFactorInfo] 6701 6702 References: 6703 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6704 @*/ 6705 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6706 { 6707 PetscErrorCode ierr; 6708 6709 PetscFunctionBegin; 6710 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6711 PetscValidType(mat,1); 6712 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 6713 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 6714 PetscValidPointer(info,4); 6715 PetscValidPointer(fact,5); 6716 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6717 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6718 if (!fact->ops->ilufactorsymbolic) { 6719 MatSolverType stype; 6720 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr); 6721 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6722 } 6723 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6724 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6725 MatCheckPreallocated(mat,2); 6726 6727 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6728 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6729 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6730 PetscFunctionReturn(0); 6731 } 6732 6733 /*@C 6734 MatICCFactorSymbolic - Performs symbolic incomplete 6735 Cholesky factorization for a symmetric matrix. Use 6736 MatCholeskyFactorNumeric() to complete the factorization. 6737 6738 Collective on Mat 6739 6740 Input Parameters: 6741 + mat - the matrix 6742 . perm - row and column permutation 6743 - info - structure containing 6744 $ levels - number of levels of fill. 6745 $ expected fill - as ratio of original fill. 6746 6747 Output Parameter: 6748 . fact - the factored matrix 6749 6750 Notes: 6751 Most users should employ the KSP interface for linear solvers 6752 instead of working directly with matrix algebra routines such as this. 6753 See, e.g., KSPCreate(). 6754 6755 Level: developer 6756 6757 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6758 6759 Note: this uses the definition of level of fill as in Y. Saad, 2003 6760 6761 Developer Note: fortran interface is not autogenerated as the f90 6762 interface defintion cannot be generated correctly [due to MatFactorInfo] 6763 6764 References: 6765 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6766 @*/ 6767 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6768 { 6769 PetscErrorCode ierr; 6770 6771 PetscFunctionBegin; 6772 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6773 PetscValidType(mat,1); 6774 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6775 PetscValidPointer(info,3); 6776 PetscValidPointer(fact,4); 6777 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6778 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6779 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6780 if (!(fact)->ops->iccfactorsymbolic) { 6781 MatSolverType stype; 6782 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr); 6783 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6784 } 6785 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6786 MatCheckPreallocated(mat,2); 6787 6788 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6789 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6790 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6791 PetscFunctionReturn(0); 6792 } 6793 6794 /*@C 6795 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6796 points to an array of valid matrices, they may be reused to store the new 6797 submatrices. 6798 6799 Collective on Mat 6800 6801 Input Parameters: 6802 + mat - the matrix 6803 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6804 . irow, icol - index sets of rows and columns to extract 6805 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6806 6807 Output Parameter: 6808 . submat - the array of submatrices 6809 6810 Notes: 6811 MatCreateSubMatrices() can extract ONLY sequential submatrices 6812 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6813 to extract a parallel submatrix. 6814 6815 Some matrix types place restrictions on the row and column 6816 indices, such as that they be sorted or that they be equal to each other. 6817 6818 The index sets may not have duplicate entries. 6819 6820 When extracting submatrices from a parallel matrix, each processor can 6821 form a different submatrix by setting the rows and columns of its 6822 individual index sets according to the local submatrix desired. 6823 6824 When finished using the submatrices, the user should destroy 6825 them with MatDestroySubMatrices(). 6826 6827 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6828 original matrix has not changed from that last call to MatCreateSubMatrices(). 6829 6830 This routine creates the matrices in submat; you should NOT create them before 6831 calling it. It also allocates the array of matrix pointers submat. 6832 6833 For BAIJ matrices the index sets must respect the block structure, that is if they 6834 request one row/column in a block, they must request all rows/columns that are in 6835 that block. For example, if the block size is 2 you cannot request just row 0 and 6836 column 0. 6837 6838 Fortran Note: 6839 The Fortran interface is slightly different from that given below; it 6840 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6841 6842 Level: advanced 6843 6844 6845 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6846 @*/ 6847 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6848 { 6849 PetscErrorCode ierr; 6850 PetscInt i; 6851 PetscBool eq; 6852 6853 PetscFunctionBegin; 6854 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6855 PetscValidType(mat,1); 6856 if (n) { 6857 PetscValidPointer(irow,3); 6858 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6859 PetscValidPointer(icol,4); 6860 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6861 } 6862 PetscValidPointer(submat,6); 6863 if (n && scall == MAT_REUSE_MATRIX) { 6864 PetscValidPointer(*submat,6); 6865 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6866 } 6867 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6868 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6869 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6870 MatCheckPreallocated(mat,1); 6871 6872 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6873 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6874 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6875 for (i=0; i<n; i++) { 6876 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6877 ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr); 6878 if (eq) { 6879 ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr); 6880 } 6881 } 6882 PetscFunctionReturn(0); 6883 } 6884 6885 /*@C 6886 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6887 6888 Collective on Mat 6889 6890 Input Parameters: 6891 + mat - the matrix 6892 . n - the number of submatrixes to be extracted 6893 . irow, icol - index sets of rows and columns to extract 6894 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6895 6896 Output Parameter: 6897 . submat - the array of submatrices 6898 6899 Level: advanced 6900 6901 6902 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6903 @*/ 6904 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6905 { 6906 PetscErrorCode ierr; 6907 PetscInt i; 6908 PetscBool eq; 6909 6910 PetscFunctionBegin; 6911 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6912 PetscValidType(mat,1); 6913 if (n) { 6914 PetscValidPointer(irow,3); 6915 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6916 PetscValidPointer(icol,4); 6917 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6918 } 6919 PetscValidPointer(submat,6); 6920 if (n && scall == MAT_REUSE_MATRIX) { 6921 PetscValidPointer(*submat,6); 6922 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6923 } 6924 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6925 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6926 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6927 MatCheckPreallocated(mat,1); 6928 6929 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6930 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6931 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6932 for (i=0; i<n; i++) { 6933 ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr); 6934 if (eq) { 6935 ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr); 6936 } 6937 } 6938 PetscFunctionReturn(0); 6939 } 6940 6941 /*@C 6942 MatDestroyMatrices - Destroys an array of matrices. 6943 6944 Collective on Mat 6945 6946 Input Parameters: 6947 + n - the number of local matrices 6948 - mat - the matrices (note that this is a pointer to the array of matrices) 6949 6950 Level: advanced 6951 6952 Notes: 6953 Frees not only the matrices, but also the array that contains the matrices 6954 In Fortran will not free the array. 6955 6956 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6957 @*/ 6958 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6959 { 6960 PetscErrorCode ierr; 6961 PetscInt i; 6962 6963 PetscFunctionBegin; 6964 if (!*mat) PetscFunctionReturn(0); 6965 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6966 PetscValidPointer(mat,2); 6967 6968 for (i=0; i<n; i++) { 6969 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6970 } 6971 6972 /* memory is allocated even if n = 0 */ 6973 ierr = PetscFree(*mat);CHKERRQ(ierr); 6974 PetscFunctionReturn(0); 6975 } 6976 6977 /*@C 6978 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6979 6980 Collective on Mat 6981 6982 Input Parameters: 6983 + n - the number of local matrices 6984 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6985 sequence of MatCreateSubMatrices()) 6986 6987 Level: advanced 6988 6989 Notes: 6990 Frees not only the matrices, but also the array that contains the matrices 6991 In Fortran will not free the array. 6992 6993 .seealso: MatCreateSubMatrices() 6994 @*/ 6995 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6996 { 6997 PetscErrorCode ierr; 6998 Mat mat0; 6999 7000 PetscFunctionBegin; 7001 if (!*mat) PetscFunctionReturn(0); 7002 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7003 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 7004 PetscValidPointer(mat,2); 7005 7006 mat0 = (*mat)[0]; 7007 if (mat0 && mat0->ops->destroysubmatrices) { 7008 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 7009 } else { 7010 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 7011 } 7012 PetscFunctionReturn(0); 7013 } 7014 7015 /*@C 7016 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 7017 7018 Collective on Mat 7019 7020 Input Parameters: 7021 . mat - the matrix 7022 7023 Output Parameter: 7024 . matstruct - the sequential matrix with the nonzero structure of mat 7025 7026 Level: intermediate 7027 7028 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 7029 @*/ 7030 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7031 { 7032 PetscErrorCode ierr; 7033 7034 PetscFunctionBegin; 7035 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7036 PetscValidPointer(matstruct,2); 7037 7038 PetscValidType(mat,1); 7039 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7040 MatCheckPreallocated(mat,1); 7041 7042 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 7043 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7044 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 7045 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7046 PetscFunctionReturn(0); 7047 } 7048 7049 /*@C 7050 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7051 7052 Collective on Mat 7053 7054 Input Parameters: 7055 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7056 sequence of MatGetSequentialNonzeroStructure()) 7057 7058 Level: advanced 7059 7060 Notes: 7061 Frees not only the matrices, but also the array that contains the matrices 7062 7063 .seealso: MatGetSeqNonzeroStructure() 7064 @*/ 7065 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7066 { 7067 PetscErrorCode ierr; 7068 7069 PetscFunctionBegin; 7070 PetscValidPointer(mat,1); 7071 ierr = MatDestroy(mat);CHKERRQ(ierr); 7072 PetscFunctionReturn(0); 7073 } 7074 7075 /*@ 7076 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7077 replaces the index sets by larger ones that represent submatrices with 7078 additional overlap. 7079 7080 Collective on Mat 7081 7082 Input Parameters: 7083 + mat - the matrix 7084 . n - the number of index sets 7085 . is - the array of index sets (these index sets will changed during the call) 7086 - ov - the additional overlap requested 7087 7088 Options Database: 7089 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7090 7091 Level: developer 7092 7093 7094 .seealso: MatCreateSubMatrices() 7095 @*/ 7096 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7097 { 7098 PetscErrorCode ierr; 7099 7100 PetscFunctionBegin; 7101 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7102 PetscValidType(mat,1); 7103 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7104 if (n) { 7105 PetscValidPointer(is,3); 7106 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7107 } 7108 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7109 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7110 MatCheckPreallocated(mat,1); 7111 7112 if (!ov) PetscFunctionReturn(0); 7113 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7114 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7115 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7116 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7117 PetscFunctionReturn(0); 7118 } 7119 7120 7121 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7122 7123 /*@ 7124 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7125 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7126 additional overlap. 7127 7128 Collective on Mat 7129 7130 Input Parameters: 7131 + mat - the matrix 7132 . n - the number of index sets 7133 . is - the array of index sets (these index sets will changed during the call) 7134 - ov - the additional overlap requested 7135 7136 Options Database: 7137 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7138 7139 Level: developer 7140 7141 7142 .seealso: MatCreateSubMatrices() 7143 @*/ 7144 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7145 { 7146 PetscInt i; 7147 PetscErrorCode ierr; 7148 7149 PetscFunctionBegin; 7150 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7151 PetscValidType(mat,1); 7152 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7153 if (n) { 7154 PetscValidPointer(is,3); 7155 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7156 } 7157 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7158 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7159 MatCheckPreallocated(mat,1); 7160 if (!ov) PetscFunctionReturn(0); 7161 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7162 for (i=0; i<n; i++){ 7163 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7164 } 7165 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7166 PetscFunctionReturn(0); 7167 } 7168 7169 7170 7171 7172 /*@ 7173 MatGetBlockSize - Returns the matrix block size. 7174 7175 Not Collective 7176 7177 Input Parameter: 7178 . mat - the matrix 7179 7180 Output Parameter: 7181 . bs - block size 7182 7183 Notes: 7184 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7185 7186 If the block size has not been set yet this routine returns 1. 7187 7188 Level: intermediate 7189 7190 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7191 @*/ 7192 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7193 { 7194 PetscFunctionBegin; 7195 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7196 PetscValidIntPointer(bs,2); 7197 *bs = PetscAbs(mat->rmap->bs); 7198 PetscFunctionReturn(0); 7199 } 7200 7201 /*@ 7202 MatGetBlockSizes - Returns the matrix block row and column sizes. 7203 7204 Not Collective 7205 7206 Input Parameter: 7207 . mat - the matrix 7208 7209 Output Parameter: 7210 + rbs - row block size 7211 - cbs - column block size 7212 7213 Notes: 7214 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7215 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7216 7217 If a block size has not been set yet this routine returns 1. 7218 7219 Level: intermediate 7220 7221 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7222 @*/ 7223 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7224 { 7225 PetscFunctionBegin; 7226 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7227 if (rbs) PetscValidIntPointer(rbs,2); 7228 if (cbs) PetscValidIntPointer(cbs,3); 7229 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7230 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7231 PetscFunctionReturn(0); 7232 } 7233 7234 /*@ 7235 MatSetBlockSize - Sets the matrix block size. 7236 7237 Logically Collective on Mat 7238 7239 Input Parameters: 7240 + mat - the matrix 7241 - bs - block size 7242 7243 Notes: 7244 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7245 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7246 7247 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7248 is compatible with the matrix local sizes. 7249 7250 Level: intermediate 7251 7252 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7253 @*/ 7254 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7255 { 7256 PetscErrorCode ierr; 7257 7258 PetscFunctionBegin; 7259 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7260 PetscValidLogicalCollectiveInt(mat,bs,2); 7261 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7262 PetscFunctionReturn(0); 7263 } 7264 7265 /*@ 7266 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7267 7268 Logically Collective on Mat 7269 7270 Input Parameters: 7271 + mat - the matrix 7272 . nblocks - the number of blocks on this process 7273 - bsizes - the block sizes 7274 7275 Notes: 7276 Currently used by PCVPBJACOBI for SeqAIJ matrices 7277 7278 Level: intermediate 7279 7280 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7281 @*/ 7282 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7283 { 7284 PetscErrorCode ierr; 7285 PetscInt i,ncnt = 0, nlocal; 7286 7287 PetscFunctionBegin; 7288 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7289 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7290 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7291 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7292 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); 7293 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7294 mat->nblocks = nblocks; 7295 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7296 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr); 7297 PetscFunctionReturn(0); 7298 } 7299 7300 /*@C 7301 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7302 7303 Logically Collective on Mat 7304 7305 Input Parameters: 7306 . mat - the matrix 7307 7308 Output Parameters: 7309 + nblocks - the number of blocks on this process 7310 - bsizes - the block sizes 7311 7312 Notes: Currently not supported from Fortran 7313 7314 Level: intermediate 7315 7316 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7317 @*/ 7318 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7319 { 7320 PetscFunctionBegin; 7321 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7322 *nblocks = mat->nblocks; 7323 *bsizes = mat->bsizes; 7324 PetscFunctionReturn(0); 7325 } 7326 7327 /*@ 7328 MatSetBlockSizes - Sets the matrix block row and column sizes. 7329 7330 Logically Collective on Mat 7331 7332 Input Parameters: 7333 + mat - the matrix 7334 . rbs - row block size 7335 - cbs - column block size 7336 7337 Notes: 7338 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7339 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7340 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7341 7342 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7343 are compatible with the matrix local sizes. 7344 7345 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7346 7347 Level: intermediate 7348 7349 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7350 @*/ 7351 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7352 { 7353 PetscErrorCode ierr; 7354 7355 PetscFunctionBegin; 7356 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7357 PetscValidLogicalCollectiveInt(mat,rbs,2); 7358 PetscValidLogicalCollectiveInt(mat,cbs,3); 7359 if (mat->ops->setblocksizes) { 7360 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7361 } 7362 if (mat->rmap->refcnt) { 7363 ISLocalToGlobalMapping l2g = NULL; 7364 PetscLayout nmap = NULL; 7365 7366 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7367 if (mat->rmap->mapping) { 7368 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7369 } 7370 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7371 mat->rmap = nmap; 7372 mat->rmap->mapping = l2g; 7373 } 7374 if (mat->cmap->refcnt) { 7375 ISLocalToGlobalMapping l2g = NULL; 7376 PetscLayout nmap = NULL; 7377 7378 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7379 if (mat->cmap->mapping) { 7380 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7381 } 7382 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7383 mat->cmap = nmap; 7384 mat->cmap->mapping = l2g; 7385 } 7386 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7387 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7388 PetscFunctionReturn(0); 7389 } 7390 7391 /*@ 7392 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7393 7394 Logically Collective on Mat 7395 7396 Input Parameters: 7397 + mat - the matrix 7398 . fromRow - matrix from which to copy row block size 7399 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7400 7401 Level: developer 7402 7403 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7404 @*/ 7405 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7406 { 7407 PetscErrorCode ierr; 7408 7409 PetscFunctionBegin; 7410 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7411 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7412 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7413 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7414 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7415 PetscFunctionReturn(0); 7416 } 7417 7418 /*@ 7419 MatResidual - Default routine to calculate the residual. 7420 7421 Collective on Mat 7422 7423 Input Parameters: 7424 + mat - the matrix 7425 . b - the right-hand-side 7426 - x - the approximate solution 7427 7428 Output Parameter: 7429 . r - location to store the residual 7430 7431 Level: developer 7432 7433 .seealso: PCMGSetResidual() 7434 @*/ 7435 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7436 { 7437 PetscErrorCode ierr; 7438 7439 PetscFunctionBegin; 7440 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7441 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7442 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7443 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7444 PetscValidType(mat,1); 7445 MatCheckPreallocated(mat,1); 7446 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7447 if (!mat->ops->residual) { 7448 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7449 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7450 } else { 7451 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7452 } 7453 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7454 PetscFunctionReturn(0); 7455 } 7456 7457 /*@C 7458 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7459 7460 Collective on Mat 7461 7462 Input Parameters: 7463 + mat - the matrix 7464 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7465 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7466 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7467 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7468 always used. 7469 7470 Output Parameters: 7471 + n - number of rows in the (possibly compressed) matrix 7472 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7473 . ja - the column indices 7474 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7475 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7476 7477 Level: developer 7478 7479 Notes: 7480 You CANNOT change any of the ia[] or ja[] values. 7481 7482 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7483 7484 Fortran Notes: 7485 In Fortran use 7486 $ 7487 $ PetscInt ia(1), ja(1) 7488 $ PetscOffset iia, jja 7489 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7490 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7491 7492 or 7493 $ 7494 $ PetscInt, pointer :: ia(:),ja(:) 7495 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7496 $ ! Access the ith and jth entries via ia(i) and ja(j) 7497 7498 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7499 @*/ 7500 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7501 { 7502 PetscErrorCode ierr; 7503 7504 PetscFunctionBegin; 7505 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7506 PetscValidType(mat,1); 7507 PetscValidIntPointer(n,5); 7508 if (ia) PetscValidIntPointer(ia,6); 7509 if (ja) PetscValidIntPointer(ja,7); 7510 PetscValidIntPointer(done,8); 7511 MatCheckPreallocated(mat,1); 7512 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7513 else { 7514 *done = PETSC_TRUE; 7515 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7516 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7517 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7518 } 7519 PetscFunctionReturn(0); 7520 } 7521 7522 /*@C 7523 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7524 7525 Collective on Mat 7526 7527 Input Parameters: 7528 + mat - the matrix 7529 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7530 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7531 symmetrized 7532 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7533 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7534 always used. 7535 . n - number of columns in the (possibly compressed) matrix 7536 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7537 - ja - the row indices 7538 7539 Output Parameters: 7540 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7541 7542 Level: developer 7543 7544 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7545 @*/ 7546 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7547 { 7548 PetscErrorCode ierr; 7549 7550 PetscFunctionBegin; 7551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7552 PetscValidType(mat,1); 7553 PetscValidIntPointer(n,4); 7554 if (ia) PetscValidIntPointer(ia,5); 7555 if (ja) PetscValidIntPointer(ja,6); 7556 PetscValidIntPointer(done,7); 7557 MatCheckPreallocated(mat,1); 7558 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7559 else { 7560 *done = PETSC_TRUE; 7561 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7562 } 7563 PetscFunctionReturn(0); 7564 } 7565 7566 /*@C 7567 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7568 MatGetRowIJ(). 7569 7570 Collective on Mat 7571 7572 Input Parameters: 7573 + mat - the matrix 7574 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7575 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7576 symmetrized 7577 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7578 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7579 always used. 7580 . n - size of (possibly compressed) matrix 7581 . ia - the row pointers 7582 - ja - the column indices 7583 7584 Output Parameters: 7585 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7586 7587 Note: 7588 This routine zeros out n, ia, and ja. This is to prevent accidental 7589 us of the array after it has been restored. If you pass NULL, it will 7590 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7591 7592 Level: developer 7593 7594 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7595 @*/ 7596 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7597 { 7598 PetscErrorCode ierr; 7599 7600 PetscFunctionBegin; 7601 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7602 PetscValidType(mat,1); 7603 if (ia) PetscValidIntPointer(ia,6); 7604 if (ja) PetscValidIntPointer(ja,7); 7605 PetscValidIntPointer(done,8); 7606 MatCheckPreallocated(mat,1); 7607 7608 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7609 else { 7610 *done = PETSC_TRUE; 7611 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7612 if (n) *n = 0; 7613 if (ia) *ia = NULL; 7614 if (ja) *ja = NULL; 7615 } 7616 PetscFunctionReturn(0); 7617 } 7618 7619 /*@C 7620 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7621 MatGetColumnIJ(). 7622 7623 Collective on Mat 7624 7625 Input Parameters: 7626 + mat - the matrix 7627 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7628 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7629 symmetrized 7630 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7631 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7632 always used. 7633 7634 Output Parameters: 7635 + n - size of (possibly compressed) matrix 7636 . ia - the column pointers 7637 . ja - the row indices 7638 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7639 7640 Level: developer 7641 7642 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7643 @*/ 7644 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7645 { 7646 PetscErrorCode ierr; 7647 7648 PetscFunctionBegin; 7649 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7650 PetscValidType(mat,1); 7651 if (ia) PetscValidIntPointer(ia,5); 7652 if (ja) PetscValidIntPointer(ja,6); 7653 PetscValidIntPointer(done,7); 7654 MatCheckPreallocated(mat,1); 7655 7656 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7657 else { 7658 *done = PETSC_TRUE; 7659 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7660 if (n) *n = 0; 7661 if (ia) *ia = NULL; 7662 if (ja) *ja = NULL; 7663 } 7664 PetscFunctionReturn(0); 7665 } 7666 7667 /*@C 7668 MatColoringPatch -Used inside matrix coloring routines that 7669 use MatGetRowIJ() and/or MatGetColumnIJ(). 7670 7671 Collective on Mat 7672 7673 Input Parameters: 7674 + mat - the matrix 7675 . ncolors - max color value 7676 . n - number of entries in colorarray 7677 - colorarray - array indicating color for each column 7678 7679 Output Parameters: 7680 . iscoloring - coloring generated using colorarray information 7681 7682 Level: developer 7683 7684 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7685 7686 @*/ 7687 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7688 { 7689 PetscErrorCode ierr; 7690 7691 PetscFunctionBegin; 7692 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7693 PetscValidType(mat,1); 7694 PetscValidIntPointer(colorarray,4); 7695 PetscValidPointer(iscoloring,5); 7696 MatCheckPreallocated(mat,1); 7697 7698 if (!mat->ops->coloringpatch) { 7699 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7700 } else { 7701 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7702 } 7703 PetscFunctionReturn(0); 7704 } 7705 7706 7707 /*@ 7708 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7709 7710 Logically Collective on Mat 7711 7712 Input Parameter: 7713 . mat - the factored matrix to be reset 7714 7715 Notes: 7716 This routine should be used only with factored matrices formed by in-place 7717 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7718 format). This option can save memory, for example, when solving nonlinear 7719 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7720 ILU(0) preconditioner. 7721 7722 Note that one can specify in-place ILU(0) factorization by calling 7723 .vb 7724 PCType(pc,PCILU); 7725 PCFactorSeUseInPlace(pc); 7726 .ve 7727 or by using the options -pc_type ilu -pc_factor_in_place 7728 7729 In-place factorization ILU(0) can also be used as a local 7730 solver for the blocks within the block Jacobi or additive Schwarz 7731 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7732 for details on setting local solver options. 7733 7734 Most users should employ the simplified KSP interface for linear solvers 7735 instead of working directly with matrix algebra routines such as this. 7736 See, e.g., KSPCreate(). 7737 7738 Level: developer 7739 7740 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7741 7742 @*/ 7743 PetscErrorCode MatSetUnfactored(Mat mat) 7744 { 7745 PetscErrorCode ierr; 7746 7747 PetscFunctionBegin; 7748 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7749 PetscValidType(mat,1); 7750 MatCheckPreallocated(mat,1); 7751 mat->factortype = MAT_FACTOR_NONE; 7752 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7753 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7754 PetscFunctionReturn(0); 7755 } 7756 7757 /*MC 7758 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7759 7760 Synopsis: 7761 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7762 7763 Not collective 7764 7765 Input Parameter: 7766 . x - matrix 7767 7768 Output Parameters: 7769 + xx_v - the Fortran90 pointer to the array 7770 - ierr - error code 7771 7772 Example of Usage: 7773 .vb 7774 PetscScalar, pointer xx_v(:,:) 7775 .... 7776 call MatDenseGetArrayF90(x,xx_v,ierr) 7777 a = xx_v(3) 7778 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7779 .ve 7780 7781 Level: advanced 7782 7783 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7784 7785 M*/ 7786 7787 /*MC 7788 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7789 accessed with MatDenseGetArrayF90(). 7790 7791 Synopsis: 7792 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7793 7794 Not collective 7795 7796 Input Parameters: 7797 + x - matrix 7798 - xx_v - the Fortran90 pointer to the array 7799 7800 Output Parameter: 7801 . ierr - error code 7802 7803 Example of Usage: 7804 .vb 7805 PetscScalar, pointer xx_v(:,:) 7806 .... 7807 call MatDenseGetArrayF90(x,xx_v,ierr) 7808 a = xx_v(3) 7809 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7810 .ve 7811 7812 Level: advanced 7813 7814 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7815 7816 M*/ 7817 7818 7819 /*MC 7820 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7821 7822 Synopsis: 7823 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7824 7825 Not collective 7826 7827 Input Parameter: 7828 . x - matrix 7829 7830 Output Parameters: 7831 + xx_v - the Fortran90 pointer to the array 7832 - ierr - error code 7833 7834 Example of Usage: 7835 .vb 7836 PetscScalar, pointer xx_v(:) 7837 .... 7838 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7839 a = xx_v(3) 7840 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7841 .ve 7842 7843 Level: advanced 7844 7845 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7846 7847 M*/ 7848 7849 /*MC 7850 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7851 accessed with MatSeqAIJGetArrayF90(). 7852 7853 Synopsis: 7854 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7855 7856 Not collective 7857 7858 Input Parameters: 7859 + x - matrix 7860 - xx_v - the Fortran90 pointer to the array 7861 7862 Output Parameter: 7863 . ierr - error code 7864 7865 Example of Usage: 7866 .vb 7867 PetscScalar, pointer xx_v(:) 7868 .... 7869 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7870 a = xx_v(3) 7871 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7872 .ve 7873 7874 Level: advanced 7875 7876 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7877 7878 M*/ 7879 7880 7881 /*@ 7882 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7883 as the original matrix. 7884 7885 Collective on Mat 7886 7887 Input Parameters: 7888 + mat - the original matrix 7889 . isrow - parallel IS containing the rows this processor should obtain 7890 . 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. 7891 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7892 7893 Output Parameter: 7894 . newmat - the new submatrix, of the same type as the old 7895 7896 Level: advanced 7897 7898 Notes: 7899 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7900 7901 Some matrix types place restrictions on the row and column indices, such 7902 as that they be sorted or that they be equal to each other. 7903 7904 The index sets may not have duplicate entries. 7905 7906 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7907 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7908 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7909 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7910 you are finished using it. 7911 7912 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7913 the input matrix. 7914 7915 If iscol is NULL then all columns are obtained (not supported in Fortran). 7916 7917 Example usage: 7918 Consider the following 8x8 matrix with 34 non-zero values, that is 7919 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7920 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7921 as follows: 7922 7923 .vb 7924 1 2 0 | 0 3 0 | 0 4 7925 Proc0 0 5 6 | 7 0 0 | 8 0 7926 9 0 10 | 11 0 0 | 12 0 7927 ------------------------------------- 7928 13 0 14 | 15 16 17 | 0 0 7929 Proc1 0 18 0 | 19 20 21 | 0 0 7930 0 0 0 | 22 23 0 | 24 0 7931 ------------------------------------- 7932 Proc2 25 26 27 | 0 0 28 | 29 0 7933 30 0 0 | 31 32 33 | 0 34 7934 .ve 7935 7936 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7937 7938 .vb 7939 2 0 | 0 3 0 | 0 7940 Proc0 5 6 | 7 0 0 | 8 7941 ------------------------------- 7942 Proc1 18 0 | 19 20 21 | 0 7943 ------------------------------- 7944 Proc2 26 27 | 0 0 28 | 29 7945 0 0 | 31 32 33 | 0 7946 .ve 7947 7948 7949 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate() 7950 @*/ 7951 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7952 { 7953 PetscErrorCode ierr; 7954 PetscMPIInt size; 7955 Mat *local; 7956 IS iscoltmp; 7957 PetscBool flg; 7958 7959 PetscFunctionBegin; 7960 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7961 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7962 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7963 PetscValidPointer(newmat,5); 7964 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7965 PetscValidType(mat,1); 7966 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7967 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7968 7969 MatCheckPreallocated(mat,1); 7970 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7971 7972 if (!iscol || isrow == iscol) { 7973 PetscBool stride; 7974 PetscMPIInt grabentirematrix = 0,grab; 7975 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7976 if (stride) { 7977 PetscInt first,step,n,rstart,rend; 7978 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7979 if (step == 1) { 7980 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7981 if (rstart == first) { 7982 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7983 if (n == rend-rstart) { 7984 grabentirematrix = 1; 7985 } 7986 } 7987 } 7988 } 7989 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7990 if (grab) { 7991 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7992 if (cll == MAT_INITIAL_MATRIX) { 7993 *newmat = mat; 7994 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7995 } 7996 PetscFunctionReturn(0); 7997 } 7998 } 7999 8000 if (!iscol) { 8001 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 8002 } else { 8003 iscoltmp = iscol; 8004 } 8005 8006 /* if original matrix is on just one processor then use submatrix generated */ 8007 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8008 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 8009 goto setproperties; 8010 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8011 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8012 *newmat = *local; 8013 ierr = PetscFree(local);CHKERRQ(ierr); 8014 goto setproperties; 8015 } else if (!mat->ops->createsubmatrix) { 8016 /* Create a new matrix type that implements the operation using the full matrix */ 8017 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8018 switch (cll) { 8019 case MAT_INITIAL_MATRIX: 8020 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8021 break; 8022 case MAT_REUSE_MATRIX: 8023 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8024 break; 8025 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8026 } 8027 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8028 goto setproperties; 8029 } 8030 8031 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8032 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8033 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8034 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8035 8036 setproperties: 8037 ierr = ISEqualUnsorted(isrow,iscoltmp,&flg);CHKERRQ(ierr); 8038 if (flg) { 8039 ierr = MatPropagateSymmetryOptions(mat,*newmat);CHKERRQ(ierr); 8040 } 8041 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8042 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8043 PetscFunctionReturn(0); 8044 } 8045 8046 /*@ 8047 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8048 8049 Not Collective 8050 8051 Input Parameters: 8052 + A - the matrix we wish to propagate options from 8053 - B - the matrix we wish to propagate options to 8054 8055 Level: beginner 8056 8057 Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC 8058 8059 .seealso: MatSetOption() 8060 @*/ 8061 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8062 { 8063 PetscErrorCode ierr; 8064 8065 PetscFunctionBegin; 8066 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8067 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 8068 if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */ 8069 ierr = MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal);CHKERRQ(ierr); 8070 } 8071 if (A->structurally_symmetric_set) { 8072 ierr = MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric);CHKERRQ(ierr); 8073 } 8074 if (A->hermitian_set) { 8075 ierr = MatSetOption(B,MAT_HERMITIAN,A->hermitian);CHKERRQ(ierr); 8076 } 8077 if (A->spd_set) { 8078 ierr = MatSetOption(B,MAT_SPD,A->spd);CHKERRQ(ierr); 8079 } 8080 if (A->symmetric_set) { 8081 ierr = MatSetOption(B,MAT_SYMMETRIC,A->symmetric);CHKERRQ(ierr); 8082 } 8083 PetscFunctionReturn(0); 8084 } 8085 8086 /*@ 8087 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8088 used during the assembly process to store values that belong to 8089 other processors. 8090 8091 Not Collective 8092 8093 Input Parameters: 8094 + mat - the matrix 8095 . size - the initial size of the stash. 8096 - bsize - the initial size of the block-stash(if used). 8097 8098 Options Database Keys: 8099 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8100 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8101 8102 Level: intermediate 8103 8104 Notes: 8105 The block-stash is used for values set with MatSetValuesBlocked() while 8106 the stash is used for values set with MatSetValues() 8107 8108 Run with the option -info and look for output of the form 8109 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8110 to determine the appropriate value, MM, to use for size and 8111 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8112 to determine the value, BMM to use for bsize 8113 8114 8115 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8116 8117 @*/ 8118 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8119 { 8120 PetscErrorCode ierr; 8121 8122 PetscFunctionBegin; 8123 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8124 PetscValidType(mat,1); 8125 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8126 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8127 PetscFunctionReturn(0); 8128 } 8129 8130 /*@ 8131 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8132 the matrix 8133 8134 Neighbor-wise Collective on Mat 8135 8136 Input Parameters: 8137 + mat - the matrix 8138 . x,y - the vectors 8139 - w - where the result is stored 8140 8141 Level: intermediate 8142 8143 Notes: 8144 w may be the same vector as y. 8145 8146 This allows one to use either the restriction or interpolation (its transpose) 8147 matrix to do the interpolation 8148 8149 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8150 8151 @*/ 8152 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8153 { 8154 PetscErrorCode ierr; 8155 PetscInt M,N,Ny; 8156 8157 PetscFunctionBegin; 8158 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8159 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8160 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8161 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8162 PetscValidType(A,1); 8163 MatCheckPreallocated(A,1); 8164 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8165 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8166 if (M == Ny) { 8167 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8168 } else { 8169 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8170 } 8171 PetscFunctionReturn(0); 8172 } 8173 8174 /*@ 8175 MatInterpolate - y = A*x or A'*x depending on the shape of 8176 the matrix 8177 8178 Neighbor-wise Collective on Mat 8179 8180 Input Parameters: 8181 + mat - the matrix 8182 - x,y - the vectors 8183 8184 Level: intermediate 8185 8186 Notes: 8187 This allows one to use either the restriction or interpolation (its transpose) 8188 matrix to do the interpolation 8189 8190 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8191 8192 @*/ 8193 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8194 { 8195 PetscErrorCode ierr; 8196 PetscInt M,N,Ny; 8197 8198 PetscFunctionBegin; 8199 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8200 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8201 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8202 PetscValidType(A,1); 8203 MatCheckPreallocated(A,1); 8204 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8205 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8206 if (M == Ny) { 8207 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8208 } else { 8209 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8210 } 8211 PetscFunctionReturn(0); 8212 } 8213 8214 /*@ 8215 MatRestrict - y = A*x or A'*x 8216 8217 Neighbor-wise Collective on Mat 8218 8219 Input Parameters: 8220 + mat - the matrix 8221 - x,y - the vectors 8222 8223 Level: intermediate 8224 8225 Notes: 8226 This allows one to use either the restriction or interpolation (its transpose) 8227 matrix to do the restriction 8228 8229 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8230 8231 @*/ 8232 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8233 { 8234 PetscErrorCode ierr; 8235 PetscInt M,N,Ny; 8236 8237 PetscFunctionBegin; 8238 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8239 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8240 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8241 PetscValidType(A,1); 8242 MatCheckPreallocated(A,1); 8243 8244 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8245 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8246 if (M == Ny) { 8247 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8248 } else { 8249 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8250 } 8251 PetscFunctionReturn(0); 8252 } 8253 8254 /*@ 8255 MatGetNullSpace - retrieves the null space of a matrix. 8256 8257 Logically Collective on Mat 8258 8259 Input Parameters: 8260 + mat - the matrix 8261 - nullsp - the null space object 8262 8263 Level: developer 8264 8265 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8266 @*/ 8267 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8268 { 8269 PetscFunctionBegin; 8270 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8271 PetscValidPointer(nullsp,2); 8272 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8273 PetscFunctionReturn(0); 8274 } 8275 8276 /*@ 8277 MatSetNullSpace - attaches a null space to a matrix. 8278 8279 Logically Collective on Mat 8280 8281 Input Parameters: 8282 + mat - the matrix 8283 - nullsp - the null space object 8284 8285 Level: advanced 8286 8287 Notes: 8288 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8289 8290 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8291 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8292 8293 You can remove the null space by calling this routine with an nullsp of NULL 8294 8295 8296 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8297 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). 8298 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 8299 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 8300 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). 8301 8302 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8303 8304 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 8305 routine also automatically calls MatSetTransposeNullSpace(). 8306 8307 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8308 @*/ 8309 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8310 { 8311 PetscErrorCode ierr; 8312 8313 PetscFunctionBegin; 8314 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8315 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8316 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8317 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8318 mat->nullsp = nullsp; 8319 if (mat->symmetric_set && mat->symmetric) { 8320 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8321 } 8322 PetscFunctionReturn(0); 8323 } 8324 8325 /*@ 8326 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8327 8328 Logically Collective on Mat 8329 8330 Input Parameters: 8331 + mat - the matrix 8332 - nullsp - the null space object 8333 8334 Level: developer 8335 8336 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8337 @*/ 8338 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8339 { 8340 PetscFunctionBegin; 8341 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8342 PetscValidType(mat,1); 8343 PetscValidPointer(nullsp,2); 8344 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8345 PetscFunctionReturn(0); 8346 } 8347 8348 /*@ 8349 MatSetTransposeNullSpace - attaches a null space to a matrix. 8350 8351 Logically Collective on Mat 8352 8353 Input Parameters: 8354 + mat - the matrix 8355 - nullsp - the null space object 8356 8357 Level: advanced 8358 8359 Notes: 8360 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. 8361 You must also call MatSetNullSpace() 8362 8363 8364 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8365 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). 8366 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 8367 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 8368 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). 8369 8370 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8371 8372 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8373 @*/ 8374 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8375 { 8376 PetscErrorCode ierr; 8377 8378 PetscFunctionBegin; 8379 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8380 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8381 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8382 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8383 mat->transnullsp = nullsp; 8384 PetscFunctionReturn(0); 8385 } 8386 8387 /*@ 8388 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8389 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8390 8391 Logically Collective on Mat 8392 8393 Input Parameters: 8394 + mat - the matrix 8395 - nullsp - the null space object 8396 8397 Level: advanced 8398 8399 Notes: 8400 Overwrites any previous near null space that may have been attached 8401 8402 You can remove the null space by calling this routine with an nullsp of NULL 8403 8404 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8405 @*/ 8406 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8407 { 8408 PetscErrorCode ierr; 8409 8410 PetscFunctionBegin; 8411 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8412 PetscValidType(mat,1); 8413 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8414 MatCheckPreallocated(mat,1); 8415 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8416 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8417 mat->nearnullsp = nullsp; 8418 PetscFunctionReturn(0); 8419 } 8420 8421 /*@ 8422 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8423 8424 Not Collective 8425 8426 Input Parameter: 8427 . mat - the matrix 8428 8429 Output Parameter: 8430 . nullsp - the null space object, NULL if not set 8431 8432 Level: developer 8433 8434 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8435 @*/ 8436 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8437 { 8438 PetscFunctionBegin; 8439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8440 PetscValidType(mat,1); 8441 PetscValidPointer(nullsp,2); 8442 MatCheckPreallocated(mat,1); 8443 *nullsp = mat->nearnullsp; 8444 PetscFunctionReturn(0); 8445 } 8446 8447 /*@C 8448 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8449 8450 Collective on Mat 8451 8452 Input Parameters: 8453 + mat - the matrix 8454 . row - row/column permutation 8455 . fill - expected fill factor >= 1.0 8456 - level - level of fill, for ICC(k) 8457 8458 Notes: 8459 Probably really in-place only when level of fill is zero, otherwise allocates 8460 new space to store factored matrix and deletes previous memory. 8461 8462 Most users should employ the simplified KSP interface for linear solvers 8463 instead of working directly with matrix algebra routines such as this. 8464 See, e.g., KSPCreate(). 8465 8466 Level: developer 8467 8468 8469 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8470 8471 Developer Note: fortran interface is not autogenerated as the f90 8472 interface defintion cannot be generated correctly [due to MatFactorInfo] 8473 8474 @*/ 8475 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8476 { 8477 PetscErrorCode ierr; 8478 8479 PetscFunctionBegin; 8480 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8481 PetscValidType(mat,1); 8482 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8483 PetscValidPointer(info,3); 8484 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8485 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8486 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8487 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8488 MatCheckPreallocated(mat,1); 8489 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8490 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8491 PetscFunctionReturn(0); 8492 } 8493 8494 /*@ 8495 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8496 ghosted ones. 8497 8498 Not Collective 8499 8500 Input Parameters: 8501 + mat - the matrix 8502 - diag = the diagonal values, including ghost ones 8503 8504 Level: developer 8505 8506 Notes: 8507 Works only for MPIAIJ and MPIBAIJ matrices 8508 8509 .seealso: MatDiagonalScale() 8510 @*/ 8511 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8512 { 8513 PetscErrorCode ierr; 8514 PetscMPIInt size; 8515 8516 PetscFunctionBegin; 8517 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8518 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8519 PetscValidType(mat,1); 8520 8521 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8522 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8523 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8524 if (size == 1) { 8525 PetscInt n,m; 8526 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8527 ierr = MatGetSize(mat,NULL,&m);CHKERRQ(ierr); 8528 if (m == n) { 8529 ierr = MatDiagonalScale(mat,NULL,diag);CHKERRQ(ierr); 8530 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8531 } else { 8532 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8533 } 8534 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8535 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8536 PetscFunctionReturn(0); 8537 } 8538 8539 /*@ 8540 MatGetInertia - Gets the inertia from a factored matrix 8541 8542 Collective on Mat 8543 8544 Input Parameter: 8545 . mat - the matrix 8546 8547 Output Parameters: 8548 + nneg - number of negative eigenvalues 8549 . nzero - number of zero eigenvalues 8550 - npos - number of positive eigenvalues 8551 8552 Level: advanced 8553 8554 Notes: 8555 Matrix must have been factored by MatCholeskyFactor() 8556 8557 8558 @*/ 8559 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8560 { 8561 PetscErrorCode ierr; 8562 8563 PetscFunctionBegin; 8564 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8565 PetscValidType(mat,1); 8566 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8567 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8568 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8569 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8570 PetscFunctionReturn(0); 8571 } 8572 8573 /* ----------------------------------------------------------------*/ 8574 /*@C 8575 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8576 8577 Neighbor-wise Collective on Mats 8578 8579 Input Parameters: 8580 + mat - the factored matrix 8581 - b - the right-hand-side vectors 8582 8583 Output Parameter: 8584 . x - the result vectors 8585 8586 Notes: 8587 The vectors b and x cannot be the same. I.e., one cannot 8588 call MatSolves(A,x,x). 8589 8590 Notes: 8591 Most users should employ the simplified KSP interface for linear solvers 8592 instead of working directly with matrix algebra routines such as this. 8593 See, e.g., KSPCreate(). 8594 8595 Level: developer 8596 8597 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8598 @*/ 8599 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8600 { 8601 PetscErrorCode ierr; 8602 8603 PetscFunctionBegin; 8604 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8605 PetscValidType(mat,1); 8606 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8607 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8608 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8609 8610 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8611 MatCheckPreallocated(mat,1); 8612 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8613 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8614 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8615 PetscFunctionReturn(0); 8616 } 8617 8618 /*@ 8619 MatIsSymmetric - Test whether a matrix is symmetric 8620 8621 Collective on Mat 8622 8623 Input Parameter: 8624 + A - the matrix to test 8625 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8626 8627 Output Parameters: 8628 . flg - the result 8629 8630 Notes: 8631 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8632 8633 Level: intermediate 8634 8635 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8636 @*/ 8637 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8638 { 8639 PetscErrorCode ierr; 8640 8641 PetscFunctionBegin; 8642 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8643 PetscValidBoolPointer(flg,2); 8644 8645 if (!A->symmetric_set) { 8646 if (!A->ops->issymmetric) { 8647 MatType mattype; 8648 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8649 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 8650 } 8651 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8652 if (!tol) { 8653 ierr = MatSetOption(A,MAT_SYMMETRIC,*flg);CHKERRQ(ierr); 8654 } 8655 } else if (A->symmetric) { 8656 *flg = PETSC_TRUE; 8657 } else if (!tol) { 8658 *flg = PETSC_FALSE; 8659 } else { 8660 if (!A->ops->issymmetric) { 8661 MatType mattype; 8662 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8663 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 8664 } 8665 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8666 } 8667 PetscFunctionReturn(0); 8668 } 8669 8670 /*@ 8671 MatIsHermitian - Test whether a matrix is Hermitian 8672 8673 Collective on Mat 8674 8675 Input Parameter: 8676 + A - the matrix to test 8677 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8678 8679 Output Parameters: 8680 . flg - the result 8681 8682 Level: intermediate 8683 8684 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8685 MatIsSymmetricKnown(), MatIsSymmetric() 8686 @*/ 8687 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8688 { 8689 PetscErrorCode ierr; 8690 8691 PetscFunctionBegin; 8692 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8693 PetscValidBoolPointer(flg,2); 8694 8695 if (!A->hermitian_set) { 8696 if (!A->ops->ishermitian) { 8697 MatType mattype; 8698 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8699 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 8700 } 8701 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8702 if (!tol) { 8703 ierr = MatSetOption(A,MAT_HERMITIAN,*flg);CHKERRQ(ierr); 8704 } 8705 } else if (A->hermitian) { 8706 *flg = PETSC_TRUE; 8707 } else if (!tol) { 8708 *flg = PETSC_FALSE; 8709 } else { 8710 if (!A->ops->ishermitian) { 8711 MatType mattype; 8712 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8713 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 8714 } 8715 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8716 } 8717 PetscFunctionReturn(0); 8718 } 8719 8720 /*@ 8721 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8722 8723 Not Collective 8724 8725 Input Parameter: 8726 . A - the matrix to check 8727 8728 Output Parameters: 8729 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8730 - flg - the result 8731 8732 Level: advanced 8733 8734 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8735 if you want it explicitly checked 8736 8737 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8738 @*/ 8739 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8740 { 8741 PetscFunctionBegin; 8742 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8743 PetscValidPointer(set,2); 8744 PetscValidBoolPointer(flg,3); 8745 if (A->symmetric_set) { 8746 *set = PETSC_TRUE; 8747 *flg = A->symmetric; 8748 } else { 8749 *set = PETSC_FALSE; 8750 } 8751 PetscFunctionReturn(0); 8752 } 8753 8754 /*@ 8755 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8756 8757 Not Collective 8758 8759 Input Parameter: 8760 . A - the matrix to check 8761 8762 Output Parameters: 8763 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8764 - flg - the result 8765 8766 Level: advanced 8767 8768 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8769 if you want it explicitly checked 8770 8771 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8772 @*/ 8773 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8774 { 8775 PetscFunctionBegin; 8776 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8777 PetscValidPointer(set,2); 8778 PetscValidBoolPointer(flg,3); 8779 if (A->hermitian_set) { 8780 *set = PETSC_TRUE; 8781 *flg = A->hermitian; 8782 } else { 8783 *set = PETSC_FALSE; 8784 } 8785 PetscFunctionReturn(0); 8786 } 8787 8788 /*@ 8789 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8790 8791 Collective on Mat 8792 8793 Input Parameter: 8794 . A - the matrix to test 8795 8796 Output Parameters: 8797 . flg - the result 8798 8799 Level: intermediate 8800 8801 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8802 @*/ 8803 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8804 { 8805 PetscErrorCode ierr; 8806 8807 PetscFunctionBegin; 8808 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8809 PetscValidBoolPointer(flg,2); 8810 if (!A->structurally_symmetric_set) { 8811 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); 8812 ierr = (*A->ops->isstructurallysymmetric)(A,flg);CHKERRQ(ierr); 8813 ierr = MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg);CHKERRQ(ierr); 8814 } else *flg = A->structurally_symmetric; 8815 PetscFunctionReturn(0); 8816 } 8817 8818 /*@ 8819 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8820 to be communicated to other processors during the MatAssemblyBegin/End() process 8821 8822 Not collective 8823 8824 Input Parameter: 8825 . vec - the vector 8826 8827 Output Parameters: 8828 + nstash - the size of the stash 8829 . reallocs - the number of additional mallocs incurred. 8830 . bnstash - the size of the block stash 8831 - breallocs - the number of additional mallocs incurred.in the block stash 8832 8833 Level: advanced 8834 8835 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8836 8837 @*/ 8838 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8839 { 8840 PetscErrorCode ierr; 8841 8842 PetscFunctionBegin; 8843 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8844 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8845 PetscFunctionReturn(0); 8846 } 8847 8848 /*@C 8849 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8850 parallel layout 8851 8852 Collective on Mat 8853 8854 Input Parameter: 8855 . mat - the matrix 8856 8857 Output Parameter: 8858 + right - (optional) vector that the matrix can be multiplied against 8859 - left - (optional) vector that the matrix vector product can be stored in 8860 8861 Notes: 8862 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(). 8863 8864 Notes: 8865 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8866 8867 Level: advanced 8868 8869 .seealso: MatCreate(), VecDestroy() 8870 @*/ 8871 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8872 { 8873 PetscErrorCode ierr; 8874 8875 PetscFunctionBegin; 8876 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8877 PetscValidType(mat,1); 8878 if (mat->ops->getvecs) { 8879 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8880 } else { 8881 PetscInt rbs,cbs; 8882 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8883 if (right) { 8884 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8885 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8886 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8887 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8888 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8889 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8890 } 8891 if (left) { 8892 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8893 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8894 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8895 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8896 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8897 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8898 } 8899 } 8900 PetscFunctionReturn(0); 8901 } 8902 8903 /*@C 8904 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8905 with default values. 8906 8907 Not Collective 8908 8909 Input Parameters: 8910 . info - the MatFactorInfo data structure 8911 8912 8913 Notes: 8914 The solvers are generally used through the KSP and PC objects, for example 8915 PCLU, PCILU, PCCHOLESKY, PCICC 8916 8917 Level: developer 8918 8919 .seealso: MatFactorInfo 8920 8921 Developer Note: fortran interface is not autogenerated as the f90 8922 interface defintion cannot be generated correctly [due to MatFactorInfo] 8923 8924 @*/ 8925 8926 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8927 { 8928 PetscErrorCode ierr; 8929 8930 PetscFunctionBegin; 8931 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8932 PetscFunctionReturn(0); 8933 } 8934 8935 /*@ 8936 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8937 8938 Collective on Mat 8939 8940 Input Parameters: 8941 + mat - the factored matrix 8942 - is - the index set defining the Schur indices (0-based) 8943 8944 Notes: 8945 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8946 8947 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8948 8949 Level: developer 8950 8951 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8952 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8953 8954 @*/ 8955 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8956 { 8957 PetscErrorCode ierr,(*f)(Mat,IS); 8958 8959 PetscFunctionBegin; 8960 PetscValidType(mat,1); 8961 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8962 PetscValidType(is,2); 8963 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8964 PetscCheckSameComm(mat,1,is,2); 8965 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8966 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8967 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"); 8968 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8969 ierr = (*f)(mat,is);CHKERRQ(ierr); 8970 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8971 PetscFunctionReturn(0); 8972 } 8973 8974 /*@ 8975 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8976 8977 Logically Collective on Mat 8978 8979 Input Parameters: 8980 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8981 . S - location where to return the Schur complement, can be NULL 8982 - status - the status of the Schur complement matrix, can be NULL 8983 8984 Notes: 8985 You must call MatFactorSetSchurIS() before calling this routine. 8986 8987 The routine provides a copy of the Schur matrix stored within the solver data structures. 8988 The caller must destroy the object when it is no longer needed. 8989 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 8990 8991 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) 8992 8993 Developer Notes: 8994 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 8995 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 8996 8997 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8998 8999 Level: advanced 9000 9001 References: 9002 9003 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9004 @*/ 9005 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9006 { 9007 PetscErrorCode ierr; 9008 9009 PetscFunctionBegin; 9010 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9011 if (S) PetscValidPointer(S,2); 9012 if (status) PetscValidPointer(status,3); 9013 if (S) { 9014 PetscErrorCode (*f)(Mat,Mat*); 9015 9016 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9017 if (f) { 9018 ierr = (*f)(F,S);CHKERRQ(ierr); 9019 } else { 9020 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9021 } 9022 } 9023 if (status) *status = F->schur_status; 9024 PetscFunctionReturn(0); 9025 } 9026 9027 /*@ 9028 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9029 9030 Logically Collective on Mat 9031 9032 Input Parameters: 9033 + F - the factored matrix obtained by calling MatGetFactor() 9034 . *S - location where to return the Schur complement, can be NULL 9035 - status - the status of the Schur complement matrix, can be NULL 9036 9037 Notes: 9038 You must call MatFactorSetSchurIS() before calling this routine. 9039 9040 Schur complement mode is currently implemented for sequential matrices. 9041 The routine returns a the Schur Complement stored within the data strutures of the solver. 9042 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9043 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9044 9045 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9046 9047 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9048 9049 Level: advanced 9050 9051 References: 9052 9053 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9054 @*/ 9055 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9056 { 9057 PetscFunctionBegin; 9058 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9059 if (S) PetscValidPointer(S,2); 9060 if (status) PetscValidPointer(status,3); 9061 if (S) *S = F->schur; 9062 if (status) *status = F->schur_status; 9063 PetscFunctionReturn(0); 9064 } 9065 9066 /*@ 9067 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9068 9069 Logically Collective on Mat 9070 9071 Input Parameters: 9072 + F - the factored matrix obtained by calling MatGetFactor() 9073 . *S - location where the Schur complement is stored 9074 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9075 9076 Notes: 9077 9078 Level: advanced 9079 9080 References: 9081 9082 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9083 @*/ 9084 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9085 { 9086 PetscErrorCode ierr; 9087 9088 PetscFunctionBegin; 9089 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9090 if (S) { 9091 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9092 *S = NULL; 9093 } 9094 F->schur_status = status; 9095 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9096 PetscFunctionReturn(0); 9097 } 9098 9099 /*@ 9100 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9101 9102 Logically Collective on Mat 9103 9104 Input Parameters: 9105 + F - the factored matrix obtained by calling MatGetFactor() 9106 . rhs - location where the right hand side of the Schur complement system is stored 9107 - sol - location where the solution of the Schur complement system has to be returned 9108 9109 Notes: 9110 The sizes of the vectors should match the size of the Schur complement 9111 9112 Must be called after MatFactorSetSchurIS() 9113 9114 Level: advanced 9115 9116 References: 9117 9118 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9119 @*/ 9120 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9121 { 9122 PetscErrorCode ierr; 9123 9124 PetscFunctionBegin; 9125 PetscValidType(F,1); 9126 PetscValidType(rhs,2); 9127 PetscValidType(sol,3); 9128 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9129 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9130 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9131 PetscCheckSameComm(F,1,rhs,2); 9132 PetscCheckSameComm(F,1,sol,3); 9133 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9134 switch (F->schur_status) { 9135 case MAT_FACTOR_SCHUR_FACTORED: 9136 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9137 break; 9138 case MAT_FACTOR_SCHUR_INVERTED: 9139 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9140 break; 9141 default: 9142 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9143 } 9144 PetscFunctionReturn(0); 9145 } 9146 9147 /*@ 9148 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9149 9150 Logically Collective on Mat 9151 9152 Input Parameters: 9153 + F - the factored matrix obtained by calling MatGetFactor() 9154 . rhs - location where the right hand side of the Schur complement system is stored 9155 - sol - location where the solution of the Schur complement system has to be returned 9156 9157 Notes: 9158 The sizes of the vectors should match the size of the Schur complement 9159 9160 Must be called after MatFactorSetSchurIS() 9161 9162 Level: advanced 9163 9164 References: 9165 9166 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9167 @*/ 9168 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9169 { 9170 PetscErrorCode ierr; 9171 9172 PetscFunctionBegin; 9173 PetscValidType(F,1); 9174 PetscValidType(rhs,2); 9175 PetscValidType(sol,3); 9176 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9177 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9178 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9179 PetscCheckSameComm(F,1,rhs,2); 9180 PetscCheckSameComm(F,1,sol,3); 9181 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9182 switch (F->schur_status) { 9183 case MAT_FACTOR_SCHUR_FACTORED: 9184 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9185 break; 9186 case MAT_FACTOR_SCHUR_INVERTED: 9187 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9188 break; 9189 default: 9190 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9191 } 9192 PetscFunctionReturn(0); 9193 } 9194 9195 /*@ 9196 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9197 9198 Logically Collective on Mat 9199 9200 Input Parameters: 9201 . F - the factored matrix obtained by calling MatGetFactor() 9202 9203 Notes: 9204 Must be called after MatFactorSetSchurIS(). 9205 9206 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9207 9208 Level: advanced 9209 9210 References: 9211 9212 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9213 @*/ 9214 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9215 { 9216 PetscErrorCode ierr; 9217 9218 PetscFunctionBegin; 9219 PetscValidType(F,1); 9220 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9221 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9222 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9223 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9224 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9225 PetscFunctionReturn(0); 9226 } 9227 9228 /*@ 9229 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9230 9231 Logically Collective on Mat 9232 9233 Input Parameters: 9234 . F - the factored matrix obtained by calling MatGetFactor() 9235 9236 Notes: 9237 Must be called after MatFactorSetSchurIS(). 9238 9239 Level: advanced 9240 9241 References: 9242 9243 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9244 @*/ 9245 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9246 { 9247 PetscErrorCode ierr; 9248 9249 PetscFunctionBegin; 9250 PetscValidType(F,1); 9251 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9252 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9253 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9254 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9255 PetscFunctionReturn(0); 9256 } 9257 9258 /*@ 9259 MatPtAP - Creates the matrix product C = P^T * A * P 9260 9261 Neighbor-wise Collective on Mat 9262 9263 Input Parameters: 9264 + A - the matrix 9265 . P - the projection matrix 9266 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9267 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9268 if the result is a dense matrix this is irrelevent 9269 9270 Output Parameters: 9271 . C - the product matrix 9272 9273 Notes: 9274 C will be created and must be destroyed by the user with MatDestroy(). 9275 9276 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9277 9278 Level: intermediate 9279 9280 .seealso: MatMatMult(), MatRARt() 9281 @*/ 9282 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9283 { 9284 PetscErrorCode ierr; 9285 9286 PetscFunctionBegin; 9287 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9288 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9289 9290 if (scall == MAT_INITIAL_MATRIX) { 9291 ierr = MatProductCreate(A,P,NULL,C);CHKERRQ(ierr); 9292 ierr = MatProductSetType(*C,MATPRODUCT_PtAP);CHKERRQ(ierr); 9293 ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr); 9294 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr); 9295 9296 (*C)->product->api_user = PETSC_TRUE; 9297 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr); 9298 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); 9299 ierr = MatProductSymbolic(*C);CHKERRQ(ierr); 9300 } else { /* scall == MAT_REUSE_MATRIX */ 9301 ierr = MatProductReplaceMats(A,P,NULL,*C);CHKERRQ(ierr); 9302 } 9303 9304 ierr = MatProductNumeric(*C);CHKERRQ(ierr); 9305 if (A->symmetric_set && A->symmetric) { 9306 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9307 } 9308 PetscFunctionReturn(0); 9309 } 9310 9311 /*@ 9312 MatRARt - Creates the matrix product C = R * A * R^T 9313 9314 Neighbor-wise Collective on Mat 9315 9316 Input Parameters: 9317 + A - the matrix 9318 . R - the projection matrix 9319 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9320 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9321 if the result is a dense matrix this is irrelevent 9322 9323 Output Parameters: 9324 . C - the product matrix 9325 9326 Notes: 9327 C will be created and must be destroyed by the user with MatDestroy(). 9328 9329 This routine is currently only implemented for pairs of AIJ matrices and classes 9330 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9331 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9332 We recommend using MatPtAP(). 9333 9334 Level: intermediate 9335 9336 .seealso: MatMatMult(), MatPtAP() 9337 @*/ 9338 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9339 { 9340 PetscErrorCode ierr; 9341 9342 PetscFunctionBegin; 9343 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9344 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9345 9346 if (scall == MAT_INITIAL_MATRIX) { 9347 ierr = MatProductCreate(A,R,NULL,C);CHKERRQ(ierr); 9348 ierr = MatProductSetType(*C,MATPRODUCT_RARt);CHKERRQ(ierr); 9349 ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr); 9350 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr); 9351 9352 (*C)->product->api_user = PETSC_TRUE; 9353 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr); 9354 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); 9355 ierr = MatProductSymbolic(*C);CHKERRQ(ierr); 9356 } else { /* scall == MAT_REUSE_MATRIX */ 9357 ierr = MatProductReplaceMats(A,R,NULL,*C);CHKERRQ(ierr); 9358 } 9359 9360 ierr = MatProductNumeric(*C);CHKERRQ(ierr); 9361 if (A->symmetric_set && A->symmetric) { 9362 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9363 } 9364 PetscFunctionReturn(0); 9365 } 9366 9367 9368 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9369 { 9370 PetscErrorCode ierr; 9371 9372 PetscFunctionBegin; 9373 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9374 9375 if (scall == MAT_INITIAL_MATRIX) { 9376 ierr = PetscInfo1(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype]);CHKERRQ(ierr); 9377 ierr = MatProductCreate(A,B,NULL,C);CHKERRQ(ierr); 9378 ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr); 9379 ierr = MatProductSetAlgorithm(*C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 9380 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr); 9381 9382 (*C)->product->api_user = PETSC_TRUE; 9383 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr); 9384 ierr = MatProductSymbolic(*C);CHKERRQ(ierr); 9385 } else { /* scall == MAT_REUSE_MATRIX */ 9386 Mat_Product *product = (*C)->product; 9387 9388 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); 9389 if (!product) { 9390 /* user provide the dense matrix *C without calling MatProductCreate() */ 9391 PetscBool isdense; 9392 9393 ierr = PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 9394 if (isdense) { 9395 /* user wants to reuse an assembled dense matrix */ 9396 /* Create product -- see MatCreateProduct() */ 9397 ierr = MatProductCreate_Private(A,B,NULL,*C);CHKERRQ(ierr); 9398 product = (*C)->product; 9399 product->fill = fill; 9400 product->api_user = PETSC_TRUE; 9401 product->clear = PETSC_TRUE; 9402 9403 ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr); 9404 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr); 9405 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); 9406 ierr = MatProductSymbolic(*C);CHKERRQ(ierr); 9407 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9408 } else { /* user may change input matrices A or B when REUSE */ 9409 ierr = MatProductReplaceMats(A,B,NULL,*C);CHKERRQ(ierr); 9410 } 9411 } 9412 ierr = MatProductNumeric(*C);CHKERRQ(ierr); 9413 PetscFunctionReturn(0); 9414 } 9415 9416 /*@ 9417 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9418 9419 Neighbor-wise Collective on Mat 9420 9421 Input Parameters: 9422 + A - the left matrix 9423 . B - the right matrix 9424 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9425 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9426 if the result is a dense matrix this is irrelevent 9427 9428 Output Parameters: 9429 . C - the product matrix 9430 9431 Notes: 9432 Unless scall is MAT_REUSE_MATRIX C will be created. 9433 9434 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 9435 call to this function with MAT_INITIAL_MATRIX. 9436 9437 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9438 9439 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic(C)/ReplaceMats(), and call MatProductNumeric() repeatedly. 9440 9441 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. 9442 9443 Level: intermediate 9444 9445 .seealso: MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9446 @*/ 9447 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9448 { 9449 PetscErrorCode ierr; 9450 9451 PetscFunctionBegin; 9452 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C);CHKERRQ(ierr); 9453 PetscFunctionReturn(0); 9454 } 9455 9456 /*@ 9457 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9458 9459 Neighbor-wise Collective on Mat 9460 9461 Input Parameters: 9462 + A - the left matrix 9463 . B - the right matrix 9464 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9465 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9466 9467 Output Parameters: 9468 . C - the product matrix 9469 9470 Notes: 9471 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9472 9473 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9474 9475 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9476 actually needed. 9477 9478 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9479 and for pairs of MPIDense matrices. 9480 9481 Options Database Keys: 9482 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9483 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9484 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9485 9486 Level: intermediate 9487 9488 .seealso: MatMatMult(), MatTransposeMatMult() MatPtAP() 9489 @*/ 9490 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9491 { 9492 PetscErrorCode ierr; 9493 9494 PetscFunctionBegin; 9495 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C);CHKERRQ(ierr); 9496 PetscFunctionReturn(0); 9497 } 9498 9499 /*@ 9500 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9501 9502 Neighbor-wise Collective on Mat 9503 9504 Input Parameters: 9505 + A - the left matrix 9506 . B - the right matrix 9507 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9508 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9509 9510 Output Parameters: 9511 . C - the product matrix 9512 9513 Notes: 9514 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9515 9516 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9517 9518 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9519 actually needed. 9520 9521 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9522 which inherit from SeqAIJ. C will be of same type as the input matrices. 9523 9524 Level: intermediate 9525 9526 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP() 9527 @*/ 9528 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9529 { 9530 PetscErrorCode ierr; 9531 9532 PetscFunctionBegin; 9533 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C);CHKERRQ(ierr); 9534 PetscFunctionReturn(0); 9535 } 9536 9537 /*@ 9538 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9539 9540 Neighbor-wise Collective on Mat 9541 9542 Input Parameters: 9543 + A - the left matrix 9544 . B - the middle matrix 9545 . C - the right matrix 9546 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9547 - 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 9548 if the result is a dense matrix this is irrelevent 9549 9550 Output Parameters: 9551 . D - the product matrix 9552 9553 Notes: 9554 Unless scall is MAT_REUSE_MATRIX D will be created. 9555 9556 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9557 9558 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9559 actually needed. 9560 9561 If you have many matrices with the same non-zero structure to multiply, you 9562 should use MAT_REUSE_MATRIX in all calls but the first or 9563 9564 Level: intermediate 9565 9566 .seealso: MatMatMult, MatPtAP() 9567 @*/ 9568 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9569 { 9570 PetscErrorCode ierr; 9571 9572 PetscFunctionBegin; 9573 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 9574 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9575 9576 if (scall == MAT_INITIAL_MATRIX) { 9577 ierr = MatProductCreate(A,B,C,D);CHKERRQ(ierr); 9578 ierr = MatProductSetType(*D,MATPRODUCT_ABC);CHKERRQ(ierr); 9579 ierr = MatProductSetAlgorithm(*D,"default");CHKERRQ(ierr); 9580 ierr = MatProductSetFill(*D,fill);CHKERRQ(ierr); 9581 9582 (*D)->product->api_user = PETSC_TRUE; 9583 ierr = MatProductSetFromOptions(*D);CHKERRQ(ierr); 9584 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); 9585 ierr = MatProductSymbolic(*D);CHKERRQ(ierr); 9586 } else { /* user may change input matrices when REUSE */ 9587 ierr = MatProductReplaceMats(A,B,C,*D);CHKERRQ(ierr); 9588 } 9589 ierr = MatProductNumeric(*D);CHKERRQ(ierr); 9590 PetscFunctionReturn(0); 9591 } 9592 9593 /*@ 9594 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9595 9596 Collective on Mat 9597 9598 Input Parameters: 9599 + mat - the matrix 9600 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9601 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9602 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9603 9604 Output Parameter: 9605 . matredundant - redundant matrix 9606 9607 Notes: 9608 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9609 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9610 9611 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9612 calling it. 9613 9614 Level: advanced 9615 9616 9617 .seealso: MatDestroy() 9618 @*/ 9619 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9620 { 9621 PetscErrorCode ierr; 9622 MPI_Comm comm; 9623 PetscMPIInt size; 9624 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 9625 Mat_Redundant *redund=NULL; 9626 PetscSubcomm psubcomm=NULL; 9627 MPI_Comm subcomm_in=subcomm; 9628 Mat *matseq; 9629 IS isrow,iscol; 9630 PetscBool newsubcomm=PETSC_FALSE; 9631 9632 PetscFunctionBegin; 9633 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9634 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9635 PetscValidPointer(*matredundant,5); 9636 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 9637 } 9638 9639 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 9640 if (size == 1 || nsubcomm == 1) { 9641 if (reuse == MAT_INITIAL_MATRIX) { 9642 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 9643 } else { 9644 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"); 9645 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 9646 } 9647 PetscFunctionReturn(0); 9648 } 9649 9650 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9651 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9652 MatCheckPreallocated(mat,1); 9653 9654 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 9655 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9656 /* create psubcomm, then get subcomm */ 9657 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9658 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 9659 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 9660 9661 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 9662 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 9663 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 9664 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 9665 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 9666 newsubcomm = PETSC_TRUE; 9667 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 9668 } 9669 9670 /* get isrow, iscol and a local sequential matrix matseq[0] */ 9671 if (reuse == MAT_INITIAL_MATRIX) { 9672 mloc_sub = PETSC_DECIDE; 9673 nloc_sub = PETSC_DECIDE; 9674 if (bs < 1) { 9675 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 9676 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 9677 } else { 9678 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 9679 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 9680 } 9681 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 9682 rstart = rend - mloc_sub; 9683 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 9684 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 9685 } else { /* reuse == MAT_REUSE_MATRIX */ 9686 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"); 9687 /* retrieve subcomm */ 9688 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 9689 redund = (*matredundant)->redundant; 9690 isrow = redund->isrow; 9691 iscol = redund->iscol; 9692 matseq = redund->matseq; 9693 } 9694 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 9695 9696 /* get matredundant over subcomm */ 9697 if (reuse == MAT_INITIAL_MATRIX) { 9698 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 9699 9700 /* create a supporting struct and attach it to C for reuse */ 9701 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 9702 (*matredundant)->redundant = redund; 9703 redund->isrow = isrow; 9704 redund->iscol = iscol; 9705 redund->matseq = matseq; 9706 if (newsubcomm) { 9707 redund->subcomm = subcomm; 9708 } else { 9709 redund->subcomm = MPI_COMM_NULL; 9710 } 9711 } else { 9712 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 9713 } 9714 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 9715 PetscFunctionReturn(0); 9716 } 9717 9718 /*@C 9719 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 9720 a given 'mat' object. Each submatrix can span multiple procs. 9721 9722 Collective on Mat 9723 9724 Input Parameters: 9725 + mat - the matrix 9726 . subcomm - the subcommunicator obtained by com_split(comm) 9727 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9728 9729 Output Parameter: 9730 . subMat - 'parallel submatrices each spans a given subcomm 9731 9732 Notes: 9733 The submatrix partition across processors is dictated by 'subComm' a 9734 communicator obtained by com_split(comm). The comm_split 9735 is not restriced to be grouped with consecutive original ranks. 9736 9737 Due the comm_split() usage, the parallel layout of the submatrices 9738 map directly to the layout of the original matrix [wrt the local 9739 row,col partitioning]. So the original 'DiagonalMat' naturally maps 9740 into the 'DiagonalMat' of the subMat, hence it is used directly from 9741 the subMat. However the offDiagMat looses some columns - and this is 9742 reconstructed with MatSetValues() 9743 9744 Level: advanced 9745 9746 9747 .seealso: MatCreateSubMatrices() 9748 @*/ 9749 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 9750 { 9751 PetscErrorCode ierr; 9752 PetscMPIInt commsize,subCommSize; 9753 9754 PetscFunctionBegin; 9755 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 9756 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 9757 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 9758 9759 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"); 9760 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 9761 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 9762 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 9763 PetscFunctionReturn(0); 9764 } 9765 9766 /*@ 9767 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9768 9769 Not Collective 9770 9771 Input Arguments: 9772 + mat - matrix to extract local submatrix from 9773 . isrow - local row indices for submatrix 9774 - iscol - local column indices for submatrix 9775 9776 Output Arguments: 9777 . submat - the submatrix 9778 9779 Level: intermediate 9780 9781 Notes: 9782 The submat should be returned with MatRestoreLocalSubMatrix(). 9783 9784 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 9785 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 9786 9787 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 9788 MatSetValuesBlockedLocal() will also be implemented. 9789 9790 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 9791 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 9792 9793 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 9794 @*/ 9795 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9796 { 9797 PetscErrorCode ierr; 9798 9799 PetscFunctionBegin; 9800 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9801 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9802 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9803 PetscCheckSameComm(isrow,2,iscol,3); 9804 PetscValidPointer(submat,4); 9805 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 9806 9807 if (mat->ops->getlocalsubmatrix) { 9808 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 9809 } else { 9810 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 9811 } 9812 PetscFunctionReturn(0); 9813 } 9814 9815 /*@ 9816 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 9817 9818 Not Collective 9819 9820 Input Arguments: 9821 mat - matrix to extract local submatrix from 9822 isrow - local row indices for submatrix 9823 iscol - local column indices for submatrix 9824 submat - the submatrix 9825 9826 Level: intermediate 9827 9828 .seealso: MatGetLocalSubMatrix() 9829 @*/ 9830 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9831 { 9832 PetscErrorCode ierr; 9833 9834 PetscFunctionBegin; 9835 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9836 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9837 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9838 PetscCheckSameComm(isrow,2,iscol,3); 9839 PetscValidPointer(submat,4); 9840 if (*submat) { 9841 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 9842 } 9843 9844 if (mat->ops->restorelocalsubmatrix) { 9845 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 9846 } else { 9847 ierr = MatDestroy(submat);CHKERRQ(ierr); 9848 } 9849 *submat = NULL; 9850 PetscFunctionReturn(0); 9851 } 9852 9853 /* --------------------------------------------------------*/ 9854 /*@ 9855 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 9856 9857 Collective on Mat 9858 9859 Input Parameter: 9860 . mat - the matrix 9861 9862 Output Parameter: 9863 . is - if any rows have zero diagonals this contains the list of them 9864 9865 Level: developer 9866 9867 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 9868 @*/ 9869 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 9870 { 9871 PetscErrorCode ierr; 9872 9873 PetscFunctionBegin; 9874 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9875 PetscValidType(mat,1); 9876 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9877 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9878 9879 if (!mat->ops->findzerodiagonals) { 9880 Vec diag; 9881 const PetscScalar *a; 9882 PetscInt *rows; 9883 PetscInt rStart, rEnd, r, nrow = 0; 9884 9885 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 9886 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 9887 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 9888 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 9889 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 9890 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 9891 nrow = 0; 9892 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 9893 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 9894 ierr = VecDestroy(&diag);CHKERRQ(ierr); 9895 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 9896 } else { 9897 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 9898 } 9899 PetscFunctionReturn(0); 9900 } 9901 9902 /*@ 9903 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 9904 9905 Collective on Mat 9906 9907 Input Parameter: 9908 . mat - the matrix 9909 9910 Output Parameter: 9911 . is - contains the list of rows with off block diagonal entries 9912 9913 Level: developer 9914 9915 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 9916 @*/ 9917 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 9918 { 9919 PetscErrorCode ierr; 9920 9921 PetscFunctionBegin; 9922 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9923 PetscValidType(mat,1); 9924 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9925 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9926 9927 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); 9928 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 9929 PetscFunctionReturn(0); 9930 } 9931 9932 /*@C 9933 MatInvertBlockDiagonal - Inverts the block diagonal entries. 9934 9935 Collective on Mat 9936 9937 Input Parameters: 9938 . mat - the matrix 9939 9940 Output Parameters: 9941 . values - the block inverses in column major order (FORTRAN-like) 9942 9943 Note: 9944 This routine is not available from Fortran. 9945 9946 Level: advanced 9947 9948 .seealso: MatInvertBockDiagonalMat 9949 @*/ 9950 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 9951 { 9952 PetscErrorCode ierr; 9953 9954 PetscFunctionBegin; 9955 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9956 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9957 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9958 if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 9959 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 9960 PetscFunctionReturn(0); 9961 } 9962 9963 /*@C 9964 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 9965 9966 Collective on Mat 9967 9968 Input Parameters: 9969 + mat - the matrix 9970 . nblocks - the number of blocks 9971 - bsizes - the size of each block 9972 9973 Output Parameters: 9974 . values - the block inverses in column major order (FORTRAN-like) 9975 9976 Note: 9977 This routine is not available from Fortran. 9978 9979 Level: advanced 9980 9981 .seealso: MatInvertBockDiagonal() 9982 @*/ 9983 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 9984 { 9985 PetscErrorCode ierr; 9986 9987 PetscFunctionBegin; 9988 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9989 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9990 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9991 if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name); 9992 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 9993 PetscFunctionReturn(0); 9994 } 9995 9996 /*@ 9997 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 9998 9999 Collective on Mat 10000 10001 Input Parameters: 10002 . A - the matrix 10003 10004 Output Parameters: 10005 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10006 10007 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10008 10009 Level: advanced 10010 10011 .seealso: MatInvertBockDiagonal() 10012 @*/ 10013 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10014 { 10015 PetscErrorCode ierr; 10016 const PetscScalar *vals; 10017 PetscInt *dnnz; 10018 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10019 10020 PetscFunctionBegin; 10021 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10022 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10023 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10024 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10025 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10026 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10027 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10028 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10029 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10030 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10031 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10032 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10033 for (i = rstart/bs; i < rend/bs; i++) { 10034 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10035 } 10036 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10037 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10038 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10039 PetscFunctionReturn(0); 10040 } 10041 10042 /*@C 10043 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10044 via MatTransposeColoringCreate(). 10045 10046 Collective on MatTransposeColoring 10047 10048 Input Parameter: 10049 . c - coloring context 10050 10051 Level: intermediate 10052 10053 .seealso: MatTransposeColoringCreate() 10054 @*/ 10055 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10056 { 10057 PetscErrorCode ierr; 10058 MatTransposeColoring matcolor=*c; 10059 10060 PetscFunctionBegin; 10061 if (!matcolor) PetscFunctionReturn(0); 10062 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10063 10064 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10065 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10066 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10067 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10068 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10069 if (matcolor->brows>0) { 10070 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10071 } 10072 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10073 PetscFunctionReturn(0); 10074 } 10075 10076 /*@C 10077 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10078 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10079 MatTransposeColoring to sparse B. 10080 10081 Collective on MatTransposeColoring 10082 10083 Input Parameters: 10084 + B - sparse matrix B 10085 . Btdense - symbolic dense matrix B^T 10086 - coloring - coloring context created with MatTransposeColoringCreate() 10087 10088 Output Parameter: 10089 . Btdense - dense matrix B^T 10090 10091 Level: advanced 10092 10093 Notes: 10094 These are used internally for some implementations of MatRARt() 10095 10096 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10097 10098 @*/ 10099 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10100 { 10101 PetscErrorCode ierr; 10102 10103 PetscFunctionBegin; 10104 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10105 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10106 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10107 10108 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10109 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10110 PetscFunctionReturn(0); 10111 } 10112 10113 /*@C 10114 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10115 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10116 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10117 Csp from Cden. 10118 10119 Collective on MatTransposeColoring 10120 10121 Input Parameters: 10122 + coloring - coloring context created with MatTransposeColoringCreate() 10123 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10124 10125 Output Parameter: 10126 . Csp - sparse matrix 10127 10128 Level: advanced 10129 10130 Notes: 10131 These are used internally for some implementations of MatRARt() 10132 10133 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10134 10135 @*/ 10136 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10137 { 10138 PetscErrorCode ierr; 10139 10140 PetscFunctionBegin; 10141 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10142 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10143 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10144 10145 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10146 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10147 ierr = MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10148 ierr = MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10149 PetscFunctionReturn(0); 10150 } 10151 10152 /*@C 10153 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10154 10155 Collective on Mat 10156 10157 Input Parameters: 10158 + mat - the matrix product C 10159 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10160 10161 Output Parameter: 10162 . color - the new coloring context 10163 10164 Level: intermediate 10165 10166 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10167 MatTransColoringApplyDenToSp() 10168 @*/ 10169 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10170 { 10171 MatTransposeColoring c; 10172 MPI_Comm comm; 10173 PetscErrorCode ierr; 10174 10175 PetscFunctionBegin; 10176 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10177 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10178 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10179 10180 c->ctype = iscoloring->ctype; 10181 if (mat->ops->transposecoloringcreate) { 10182 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10183 } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10184 10185 *color = c; 10186 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10187 PetscFunctionReturn(0); 10188 } 10189 10190 /*@ 10191 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10192 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10193 same, otherwise it will be larger 10194 10195 Not Collective 10196 10197 Input Parameter: 10198 . A - the matrix 10199 10200 Output Parameter: 10201 . state - the current state 10202 10203 Notes: 10204 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10205 different matrices 10206 10207 Level: intermediate 10208 10209 @*/ 10210 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10211 { 10212 PetscFunctionBegin; 10213 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10214 *state = mat->nonzerostate; 10215 PetscFunctionReturn(0); 10216 } 10217 10218 /*@ 10219 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10220 matrices from each processor 10221 10222 Collective 10223 10224 Input Parameters: 10225 + comm - the communicators the parallel matrix will live on 10226 . seqmat - the input sequential matrices 10227 . n - number of local columns (or PETSC_DECIDE) 10228 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10229 10230 Output Parameter: 10231 . mpimat - the parallel matrix generated 10232 10233 Level: advanced 10234 10235 Notes: 10236 The number of columns of the matrix in EACH processor MUST be the same. 10237 10238 @*/ 10239 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10240 { 10241 PetscErrorCode ierr; 10242 10243 PetscFunctionBegin; 10244 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10245 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"); 10246 10247 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10248 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10249 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10250 PetscFunctionReturn(0); 10251 } 10252 10253 /*@ 10254 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10255 ranks' ownership ranges. 10256 10257 Collective on A 10258 10259 Input Parameters: 10260 + A - the matrix to create subdomains from 10261 - N - requested number of subdomains 10262 10263 10264 Output Parameters: 10265 + n - number of subdomains resulting on this rank 10266 - iss - IS list with indices of subdomains on this rank 10267 10268 Level: advanced 10269 10270 Notes: 10271 number of subdomains must be smaller than the communicator size 10272 @*/ 10273 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10274 { 10275 MPI_Comm comm,subcomm; 10276 PetscMPIInt size,rank,color; 10277 PetscInt rstart,rend,k; 10278 PetscErrorCode ierr; 10279 10280 PetscFunctionBegin; 10281 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10282 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10283 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10284 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); 10285 *n = 1; 10286 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10287 color = rank/k; 10288 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10289 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10290 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10291 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10292 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10293 PetscFunctionReturn(0); 10294 } 10295 10296 /*@ 10297 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10298 10299 If the interpolation and restriction operators are the same, uses MatPtAP. 10300 If they are not the same, use MatMatMatMult. 10301 10302 Once the coarse grid problem is constructed, correct for interpolation operators 10303 that are not of full rank, which can legitimately happen in the case of non-nested 10304 geometric multigrid. 10305 10306 Input Parameters: 10307 + restrct - restriction operator 10308 . dA - fine grid matrix 10309 . interpolate - interpolation operator 10310 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10311 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10312 10313 Output Parameters: 10314 . A - the Galerkin coarse matrix 10315 10316 Options Database Key: 10317 . -pc_mg_galerkin <both,pmat,mat,none> 10318 10319 Level: developer 10320 10321 .seealso: MatPtAP(), MatMatMatMult() 10322 @*/ 10323 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10324 { 10325 PetscErrorCode ierr; 10326 IS zerorows; 10327 Vec diag; 10328 10329 PetscFunctionBegin; 10330 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10331 /* Construct the coarse grid matrix */ 10332 if (interpolate == restrct) { 10333 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10334 } else { 10335 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10336 } 10337 10338 /* If the interpolation matrix is not of full rank, A will have zero rows. 10339 This can legitimately happen in the case of non-nested geometric multigrid. 10340 In that event, we set the rows of the matrix to the rows of the identity, 10341 ignoring the equations (as the RHS will also be zero). */ 10342 10343 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10344 10345 if (zerorows != NULL) { /* if there are any zero rows */ 10346 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10347 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10348 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10349 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10350 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10351 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10352 } 10353 PetscFunctionReturn(0); 10354 } 10355 10356 /*@C 10357 MatSetOperation - Allows user to set a matrix operation for any matrix type 10358 10359 Logically Collective on Mat 10360 10361 Input Parameters: 10362 + mat - the matrix 10363 . op - the name of the operation 10364 - f - the function that provides the operation 10365 10366 Level: developer 10367 10368 Usage: 10369 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10370 $ ierr = MatCreateXXX(comm,...&A); 10371 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10372 10373 Notes: 10374 See the file include/petscmat.h for a complete list of matrix 10375 operations, which all have the form MATOP_<OPERATION>, where 10376 <OPERATION> is the name (in all capital letters) of the 10377 user interface routine (e.g., MatMult() -> MATOP_MULT). 10378 10379 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10380 sequence as the usual matrix interface routines, since they 10381 are intended to be accessed via the usual matrix interface 10382 routines, e.g., 10383 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10384 10385 In particular each function MUST return an error code of 0 on success and 10386 nonzero on failure. 10387 10388 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10389 10390 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10391 @*/ 10392 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10393 { 10394 PetscFunctionBegin; 10395 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10396 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10397 mat->ops->viewnative = mat->ops->view; 10398 } 10399 (((void(**)(void))mat->ops)[op]) = f; 10400 PetscFunctionReturn(0); 10401 } 10402 10403 /*@C 10404 MatGetOperation - Gets a matrix operation for any matrix type. 10405 10406 Not Collective 10407 10408 Input Parameters: 10409 + mat - the matrix 10410 - op - the name of the operation 10411 10412 Output Parameter: 10413 . f - the function that provides the operation 10414 10415 Level: developer 10416 10417 Usage: 10418 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10419 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10420 10421 Notes: 10422 See the file include/petscmat.h for a complete list of matrix 10423 operations, which all have the form MATOP_<OPERATION>, where 10424 <OPERATION> is the name (in all capital letters) of the 10425 user interface routine (e.g., MatMult() -> MATOP_MULT). 10426 10427 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10428 10429 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10430 @*/ 10431 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10432 { 10433 PetscFunctionBegin; 10434 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10435 *f = (((void (**)(void))mat->ops)[op]); 10436 PetscFunctionReturn(0); 10437 } 10438 10439 /*@ 10440 MatHasOperation - Determines whether the given matrix supports the particular 10441 operation. 10442 10443 Not Collective 10444 10445 Input Parameters: 10446 + mat - the matrix 10447 - op - the operation, for example, MATOP_GET_DIAGONAL 10448 10449 Output Parameter: 10450 . has - either PETSC_TRUE or PETSC_FALSE 10451 10452 Level: advanced 10453 10454 Notes: 10455 See the file include/petscmat.h for a complete list of matrix 10456 operations, which all have the form MATOP_<OPERATION>, where 10457 <OPERATION> is the name (in all capital letters) of the 10458 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10459 10460 .seealso: MatCreateShell() 10461 @*/ 10462 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10463 { 10464 PetscErrorCode ierr; 10465 10466 PetscFunctionBegin; 10467 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10468 /* symbolic product can be set before matrix type */ 10469 if (op != MATOP_PRODUCTSYMBOLIC) PetscValidType(mat,1); 10470 PetscValidPointer(has,3); 10471 if (mat->ops->hasoperation) { 10472 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10473 } else { 10474 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10475 else { 10476 *has = PETSC_FALSE; 10477 if (op == MATOP_CREATE_SUBMATRIX) { 10478 PetscMPIInt size; 10479 10480 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10481 if (size == 1) { 10482 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10483 } 10484 } 10485 } 10486 } 10487 PetscFunctionReturn(0); 10488 } 10489 10490 /*@ 10491 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10492 of the matrix are congruent 10493 10494 Collective on mat 10495 10496 Input Parameters: 10497 . mat - the matrix 10498 10499 Output Parameter: 10500 . cong - either PETSC_TRUE or PETSC_FALSE 10501 10502 Level: beginner 10503 10504 Notes: 10505 10506 .seealso: MatCreate(), MatSetSizes() 10507 @*/ 10508 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10509 { 10510 PetscErrorCode ierr; 10511 10512 PetscFunctionBegin; 10513 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10514 PetscValidType(mat,1); 10515 PetscValidPointer(cong,2); 10516 if (!mat->rmap || !mat->cmap) { 10517 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10518 PetscFunctionReturn(0); 10519 } 10520 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10521 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 10522 if (*cong) mat->congruentlayouts = 1; 10523 else mat->congruentlayouts = 0; 10524 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10525 PetscFunctionReturn(0); 10526 } 10527 10528 PetscErrorCode MatSetInf(Mat A) 10529 { 10530 PetscErrorCode ierr; 10531 10532 PetscFunctionBegin; 10533 if (!A->ops->setinf) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10534 ierr = (*A->ops->setinf)(A);CHKERRQ(ierr); 10535 PetscFunctionReturn(0); 10536 } 10537