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