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