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