1 2 /* 3 This is where the abstract matrix operations are defined 4 */ 5 6 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 7 #include <petsc/private/isimpl.h> 8 #include <petsc/private/vecimpl.h> 9 10 /* Logging support */ 11 PetscClassId MAT_CLASSID; 12 PetscClassId MAT_COLORING_CLASSID; 13 PetscClassId MAT_FDCOLORING_CLASSID; 14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 15 16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 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_SetValuesBatch; 36 PetscLogEvent MAT_ViennaCLCopyToGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 39 40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 41 42 /*@ 43 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 44 45 Logically Collective on Mat 46 47 Input Parameters: 48 + x - the matrix 49 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 50 it will create one internally. 51 52 Output Parameter: 53 . x - the matrix 54 55 Example of Usage: 56 .vb 57 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 58 MatSetRandom(x,rctx); 59 PetscRandomDestroy(rctx); 60 .ve 61 62 Level: intermediate 63 64 65 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 66 @*/ 67 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 68 { 69 PetscErrorCode ierr; 70 PetscRandom randObj = NULL; 71 72 PetscFunctionBegin; 73 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 74 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 75 PetscValidType(x,1); 76 77 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 78 79 if (!rctx) { 80 MPI_Comm comm; 81 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 82 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 83 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 84 rctx = randObj; 85 } 86 87 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 88 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 89 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 91 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 92 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 93 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 94 PetscFunctionReturn(0); 95 } 96 97 /*@ 98 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 99 100 Logically Collective on Mat 101 102 Input Parameters: 103 . mat - the factored matrix 104 105 Output Parameter: 106 + pivot - the pivot value computed 107 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 108 the share the matrix 109 110 Level: advanced 111 112 Notes: 113 This routine does not work for factorizations done with external packages. 114 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 115 116 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 117 118 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 119 @*/ 120 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 121 { 122 PetscFunctionBegin; 123 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 124 *pivot = mat->factorerror_zeropivot_value; 125 *row = mat->factorerror_zeropivot_row; 126 PetscFunctionReturn(0); 127 } 128 129 /*@ 130 MatFactorGetError - gets the error code from a factorization 131 132 Logically Collective on Mat 133 134 Input Parameters: 135 . mat - the factored matrix 136 137 Output Parameter: 138 . err - the error code 139 140 Level: advanced 141 142 Notes: 143 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 144 145 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 146 @*/ 147 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 148 { 149 PetscFunctionBegin; 150 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 151 *err = mat->factorerrortype; 152 PetscFunctionReturn(0); 153 } 154 155 /*@ 156 MatFactorClearError - clears the error code in a factorization 157 158 Logically Collective on Mat 159 160 Input Parameter: 161 . mat - the factored matrix 162 163 Level: developer 164 165 Notes: 166 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 167 168 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 169 @*/ 170 PetscErrorCode MatFactorClearError(Mat mat) 171 { 172 PetscFunctionBegin; 173 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 174 mat->factorerrortype = MAT_FACTOR_NOERROR; 175 mat->factorerror_zeropivot_value = 0.0; 176 mat->factorerror_zeropivot_row = 0; 177 PetscFunctionReturn(0); 178 } 179 180 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 181 { 182 PetscErrorCode ierr; 183 Vec r,l; 184 const PetscScalar *al; 185 PetscInt i,nz,gnz,N,n; 186 187 PetscFunctionBegin; 188 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 189 if (!cols) { /* nonzero rows */ 190 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 191 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 192 ierr = VecSet(l,0.0);CHKERRQ(ierr); 193 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 194 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 195 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 196 } else { /* nonzero columns */ 197 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 198 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 199 ierr = VecSet(r,0.0);CHKERRQ(ierr); 200 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 201 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 202 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 203 } 204 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 205 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 206 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 207 if (gnz != N) { 208 PetscInt *nzr; 209 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 210 if (nz) { 211 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 212 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 213 } 214 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 215 } else *nonzero = NULL; 216 if (!cols) { /* nonzero rows */ 217 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 218 } else { 219 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 220 } 221 ierr = VecDestroy(&l);CHKERRQ(ierr); 222 ierr = VecDestroy(&r);CHKERRQ(ierr); 223 PetscFunctionReturn(0); 224 } 225 226 /*@ 227 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 228 229 Input Parameter: 230 . A - the matrix 231 232 Output Parameter: 233 . keptrows - the rows that are not completely zero 234 235 Notes: 236 keptrows is set to NULL if all rows are nonzero. 237 238 Level: intermediate 239 240 @*/ 241 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 242 { 243 PetscErrorCode ierr; 244 245 PetscFunctionBegin; 246 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 247 PetscValidType(mat,1); 248 PetscValidPointer(keptrows,2); 249 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 250 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 251 if (!mat->ops->findnonzerorows) { 252 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 253 } else { 254 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 255 } 256 PetscFunctionReturn(0); 257 } 258 259 /*@ 260 MatFindZeroRows - Locate all rows that are completely zero in the matrix 261 262 Input Parameter: 263 . A - the matrix 264 265 Output Parameter: 266 . zerorows - the rows that are completely zero 267 268 Notes: 269 zerorows is set to NULL if no rows are zero. 270 271 Level: intermediate 272 273 @*/ 274 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 275 { 276 PetscErrorCode ierr; 277 IS keptrows; 278 PetscInt m, n; 279 280 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 281 PetscValidType(mat,1); 282 283 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 284 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 285 In keeping with this convention, we set zerorows to NULL if there are no zero 286 rows. */ 287 if (keptrows == NULL) { 288 *zerorows = NULL; 289 } else { 290 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 291 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 292 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 293 } 294 PetscFunctionReturn(0); 295 } 296 297 /*@ 298 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 299 300 Not Collective 301 302 Input Parameters: 303 . A - the matrix 304 305 Output Parameters: 306 . a - the diagonal part (which is a SEQUENTIAL matrix) 307 308 Notes: 309 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 310 Use caution, as the reference count on the returned matrix is not incremented and it is used as 311 part of the containing MPI Mat's normal operation. 312 313 Level: advanced 314 315 @*/ 316 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 317 { 318 PetscErrorCode ierr; 319 320 PetscFunctionBegin; 321 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 322 PetscValidType(A,1); 323 PetscValidPointer(a,3); 324 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 325 if (!A->ops->getdiagonalblock) { 326 PetscMPIInt size; 327 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 328 if (size == 1) { 329 *a = A; 330 PetscFunctionReturn(0); 331 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 332 } 333 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 334 PetscFunctionReturn(0); 335 } 336 337 /*@ 338 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 339 340 Collective on Mat 341 342 Input Parameters: 343 . mat - the matrix 344 345 Output Parameter: 346 . trace - the sum of the diagonal entries 347 348 Level: advanced 349 350 @*/ 351 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 352 { 353 PetscErrorCode ierr; 354 Vec diag; 355 356 PetscFunctionBegin; 357 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 358 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 359 ierr = VecSum(diag,trace);CHKERRQ(ierr); 360 ierr = VecDestroy(&diag);CHKERRQ(ierr); 361 PetscFunctionReturn(0); 362 } 363 364 /*@ 365 MatRealPart - Zeros out the imaginary part of the matrix 366 367 Logically Collective on Mat 368 369 Input Parameters: 370 . mat - the matrix 371 372 Level: advanced 373 374 375 .seealso: MatImaginaryPart() 376 @*/ 377 PetscErrorCode MatRealPart(Mat mat) 378 { 379 PetscErrorCode ierr; 380 381 PetscFunctionBegin; 382 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 383 PetscValidType(mat,1); 384 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 385 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 386 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 387 MatCheckPreallocated(mat,1); 388 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 389 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 390 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 391 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 392 } 393 #endif 394 PetscFunctionReturn(0); 395 } 396 397 /*@C 398 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 399 400 Collective on Mat 401 402 Input Parameter: 403 . mat - the matrix 404 405 Output Parameters: 406 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 407 - ghosts - the global indices of the ghost points 408 409 Notes: 410 the nghosts and ghosts are suitable to pass into VecCreateGhost() 411 412 Level: advanced 413 414 @*/ 415 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 416 { 417 PetscErrorCode ierr; 418 419 PetscFunctionBegin; 420 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 421 PetscValidType(mat,1); 422 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 423 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 424 if (!mat->ops->getghosts) { 425 if (nghosts) *nghosts = 0; 426 if (ghosts) *ghosts = 0; 427 } else { 428 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 429 } 430 PetscFunctionReturn(0); 431 } 432 433 434 /*@ 435 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 436 437 Logically Collective on Mat 438 439 Input Parameters: 440 . mat - the matrix 441 442 Level: advanced 443 444 445 .seealso: MatRealPart() 446 @*/ 447 PetscErrorCode MatImaginaryPart(Mat mat) 448 { 449 PetscErrorCode ierr; 450 451 PetscFunctionBegin; 452 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 453 PetscValidType(mat,1); 454 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 455 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 456 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 457 MatCheckPreallocated(mat,1); 458 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 459 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 460 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 461 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 462 } 463 #endif 464 PetscFunctionReturn(0); 465 } 466 467 /*@ 468 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 469 470 Not Collective 471 472 Input Parameter: 473 . mat - the matrix 474 475 Output Parameters: 476 + missing - is any diagonal missing 477 - dd - first diagonal entry that is missing (optional) on this process 478 479 Level: advanced 480 481 482 .seealso: MatRealPart() 483 @*/ 484 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 485 { 486 PetscErrorCode ierr; 487 488 PetscFunctionBegin; 489 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 490 PetscValidType(mat,1); 491 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 492 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 493 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 494 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 495 PetscFunctionReturn(0); 496 } 497 498 /*@C 499 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 500 for each row that you get to ensure that your application does 501 not bleed memory. 502 503 Not Collective 504 505 Input Parameters: 506 + mat - the matrix 507 - row - the row to get 508 509 Output Parameters: 510 + ncols - if not NULL, the number of nonzeros in the row 511 . cols - if not NULL, the column numbers 512 - vals - if not NULL, the values 513 514 Notes: 515 This routine is provided for people who need to have direct access 516 to the structure of a matrix. We hope that we provide enough 517 high-level matrix routines that few users will need it. 518 519 MatGetRow() always returns 0-based column indices, regardless of 520 whether the internal representation is 0-based (default) or 1-based. 521 522 For better efficiency, set cols and/or vals to NULL if you do 523 not wish to extract these quantities. 524 525 The user can only examine the values extracted with MatGetRow(); 526 the values cannot be altered. To change the matrix entries, one 527 must use MatSetValues(). 528 529 You can only have one call to MatGetRow() outstanding for a particular 530 matrix at a time, per processor. MatGetRow() can only obtain rows 531 associated with the given processor, it cannot get rows from the 532 other processors; for that we suggest using MatCreateSubMatrices(), then 533 MatGetRow() on the submatrix. The row index passed to MatGetRow() 534 is in the global number of rows. 535 536 Fortran Notes: 537 The calling sequence from Fortran is 538 .vb 539 MatGetRow(matrix,row,ncols,cols,values,ierr) 540 Mat matrix (input) 541 integer row (input) 542 integer ncols (output) 543 integer cols(maxcols) (output) 544 double precision (or double complex) values(maxcols) output 545 .ve 546 where maxcols >= maximum nonzeros in any row of the matrix. 547 548 549 Caution: 550 Do not try to change the contents of the output arrays (cols and vals). 551 In some cases, this may corrupt the matrix. 552 553 Level: advanced 554 555 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 556 @*/ 557 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 558 { 559 PetscErrorCode ierr; 560 PetscInt incols; 561 562 PetscFunctionBegin; 563 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 564 PetscValidType(mat,1); 565 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 566 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 567 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 568 MatCheckPreallocated(mat,1); 569 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 570 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 571 if (ncols) *ncols = incols; 572 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 573 PetscFunctionReturn(0); 574 } 575 576 /*@ 577 MatConjugate - replaces the matrix values with their complex conjugates 578 579 Logically Collective on Mat 580 581 Input Parameters: 582 . mat - the matrix 583 584 Level: advanced 585 586 .seealso: VecConjugate() 587 @*/ 588 PetscErrorCode MatConjugate(Mat mat) 589 { 590 #if defined(PETSC_USE_COMPLEX) 591 PetscErrorCode ierr; 592 593 PetscFunctionBegin; 594 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 595 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 596 if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov"); 597 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 598 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 599 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 600 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 601 } 602 #endif 603 PetscFunctionReturn(0); 604 #else 605 return 0; 606 #endif 607 } 608 609 /*@C 610 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 611 612 Not Collective 613 614 Input Parameters: 615 + mat - the matrix 616 . row - the row to get 617 . ncols, cols - the number of nonzeros and their columns 618 - vals - if nonzero the column values 619 620 Notes: 621 This routine should be called after you have finished examining the entries. 622 623 This routine zeros out ncols, cols, and vals. This is to prevent accidental 624 us of the array after it has been restored. If you pass NULL, it will 625 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 626 627 Fortran Notes: 628 The calling sequence from Fortran is 629 .vb 630 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 631 Mat matrix (input) 632 integer row (input) 633 integer ncols (output) 634 integer cols(maxcols) (output) 635 double precision (or double complex) values(maxcols) output 636 .ve 637 Where maxcols >= maximum nonzeros in any row of the matrix. 638 639 In Fortran MatRestoreRow() MUST be called after MatGetRow() 640 before another call to MatGetRow() can be made. 641 642 Level: advanced 643 644 .seealso: MatGetRow() 645 @*/ 646 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 647 { 648 PetscErrorCode ierr; 649 650 PetscFunctionBegin; 651 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 652 if (ncols) PetscValidIntPointer(ncols,3); 653 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 654 if (!mat->ops->restorerow) PetscFunctionReturn(0); 655 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 656 if (ncols) *ncols = 0; 657 if (cols) *cols = NULL; 658 if (vals) *vals = NULL; 659 PetscFunctionReturn(0); 660 } 661 662 /*@ 663 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 664 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 665 666 Not Collective 667 668 Input Parameters: 669 . mat - the matrix 670 671 Notes: 672 The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format. 673 674 Level: advanced 675 676 .seealso: MatRestoreRowUpperTriangular() 677 @*/ 678 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 679 { 680 PetscErrorCode ierr; 681 682 PetscFunctionBegin; 683 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 684 PetscValidType(mat,1); 685 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 686 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 687 MatCheckPreallocated(mat,1); 688 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 689 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 690 PetscFunctionReturn(0); 691 } 692 693 /*@ 694 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 695 696 Not Collective 697 698 Input Parameters: 699 . mat - the matrix 700 701 Notes: 702 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 703 704 705 Level: advanced 706 707 .seealso: MatGetRowUpperTriangular() 708 @*/ 709 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 710 { 711 PetscErrorCode ierr; 712 713 PetscFunctionBegin; 714 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 715 PetscValidType(mat,1); 716 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 717 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 718 MatCheckPreallocated(mat,1); 719 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 720 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 721 PetscFunctionReturn(0); 722 } 723 724 /*@C 725 MatSetOptionsPrefix - Sets the prefix used for searching for all 726 Mat options in the database. 727 728 Logically Collective on Mat 729 730 Input Parameter: 731 + A - the Mat context 732 - prefix - the prefix to prepend to all option names 733 734 Notes: 735 A hyphen (-) must NOT be given at the beginning of the prefix name. 736 The first character of all runtime options is AUTOMATICALLY the hyphen. 737 738 Level: advanced 739 740 .seealso: MatSetFromOptions() 741 @*/ 742 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 743 { 744 PetscErrorCode ierr; 745 746 PetscFunctionBegin; 747 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 748 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 749 PetscFunctionReturn(0); 750 } 751 752 /*@C 753 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 754 Mat options in the database. 755 756 Logically Collective on Mat 757 758 Input Parameters: 759 + A - the Mat context 760 - prefix - the prefix to prepend to all option names 761 762 Notes: 763 A hyphen (-) must NOT be given at the beginning of the prefix name. 764 The first character of all runtime options is AUTOMATICALLY the hyphen. 765 766 Level: advanced 767 768 .seealso: MatGetOptionsPrefix() 769 @*/ 770 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 771 { 772 PetscErrorCode ierr; 773 774 PetscFunctionBegin; 775 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 776 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 777 PetscFunctionReturn(0); 778 } 779 780 /*@C 781 MatGetOptionsPrefix - Sets the prefix used for searching for all 782 Mat options in the database. 783 784 Not Collective 785 786 Input Parameter: 787 . A - the Mat context 788 789 Output Parameter: 790 . prefix - pointer to the prefix string used 791 792 Notes: 793 On the fortran side, the user should pass in a string 'prefix' of 794 sufficient length to hold the prefix. 795 796 Level: advanced 797 798 .seealso: MatAppendOptionsPrefix() 799 @*/ 800 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 801 { 802 PetscErrorCode ierr; 803 804 PetscFunctionBegin; 805 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 806 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 807 PetscFunctionReturn(0); 808 } 809 810 /*@ 811 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 812 813 Collective on Mat 814 815 Input Parameters: 816 . A - the Mat context 817 818 Notes: 819 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 820 Currently support MPIAIJ and SEQAIJ. 821 822 Level: beginner 823 824 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 825 @*/ 826 PetscErrorCode MatResetPreallocation(Mat A) 827 { 828 PetscErrorCode ierr; 829 830 PetscFunctionBegin; 831 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 832 PetscValidType(A,1); 833 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 834 PetscFunctionReturn(0); 835 } 836 837 838 /*@ 839 MatSetUp - Sets up the internal matrix data structures for the later use. 840 841 Collective on Mat 842 843 Input Parameters: 844 . A - the Mat context 845 846 Notes: 847 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 848 849 If a suitable preallocation routine is used, this function does not need to be called. 850 851 See the Performance chapter of the PETSc users manual for how to preallocate matrices 852 853 Level: beginner 854 855 .seealso: MatCreate(), MatDestroy() 856 @*/ 857 PetscErrorCode MatSetUp(Mat A) 858 { 859 PetscMPIInt size; 860 PetscErrorCode ierr; 861 862 PetscFunctionBegin; 863 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 864 if (!((PetscObject)A)->type_name) { 865 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 866 if (size == 1) { 867 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 868 } else { 869 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 870 } 871 } 872 if (!A->preallocated && A->ops->setup) { 873 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 874 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 875 } 876 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 877 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 878 A->preallocated = PETSC_TRUE; 879 PetscFunctionReturn(0); 880 } 881 882 #if defined(PETSC_HAVE_SAWS) 883 #include <petscviewersaws.h> 884 #endif 885 /*@C 886 MatView - Visualizes a matrix object. 887 888 Collective on Mat 889 890 Input Parameters: 891 + mat - the matrix 892 - viewer - visualization context 893 894 Notes: 895 The available visualization contexts include 896 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 897 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 898 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 899 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 900 901 The user can open alternative visualization contexts with 902 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 903 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 904 specified file; corresponding input uses MatLoad() 905 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 906 an X window display 907 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 908 Currently only the sequential dense and AIJ 909 matrix types support the Socket viewer. 910 911 The user can call PetscViewerPushFormat() to specify the output 912 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 913 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 914 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 915 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 916 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 917 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 918 format common among all matrix types 919 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 920 format (which is in many cases the same as the default) 921 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 922 size and structure (not the matrix entries) 923 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 924 the matrix structure 925 926 Options Database Keys: 927 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 928 . -mat_view ::ascii_info_detail - Prints more detailed info 929 . -mat_view - Prints matrix in ASCII format 930 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 931 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 932 . -display <name> - Sets display name (default is host) 933 . -draw_pause <sec> - Sets number of seconds to pause after display 934 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 935 . -viewer_socket_machine <machine> - 936 . -viewer_socket_port <port> - 937 . -mat_view binary - save matrix to file in binary format 938 - -viewer_binary_filename <name> - 939 Level: beginner 940 941 Notes: 942 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 943 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 944 945 See the manual page for MatLoad() for the exact format of the binary file when the binary 946 viewer is used. 947 948 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 949 viewer is used. 950 951 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 952 and then use the following mouse functions. 953 + left mouse: zoom in 954 . middle mouse: zoom out 955 - right mouse: continue with the simulation 956 957 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 958 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 959 @*/ 960 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 961 { 962 PetscErrorCode ierr; 963 PetscInt rows,cols,rbs,cbs; 964 PetscBool iascii,ibinary,isstring; 965 PetscViewerFormat format; 966 PetscMPIInt size; 967 #if defined(PETSC_HAVE_SAWS) 968 PetscBool issaws; 969 #endif 970 971 PetscFunctionBegin; 972 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 973 PetscValidType(mat,1); 974 if (!viewer) { 975 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 976 } 977 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 978 PetscCheckSameComm(mat,1,viewer,2); 979 MatCheckPreallocated(mat,1); 980 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 981 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 982 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 983 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 984 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 985 if (ibinary) { 986 PetscBool mpiio; 987 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 988 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 989 } 990 991 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 992 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 993 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 994 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 995 } 996 997 #if defined(PETSC_HAVE_SAWS) 998 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 999 #endif 1000 if (iascii) { 1001 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1002 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1003 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1004 MatNullSpace nullsp,transnullsp; 1005 1006 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1007 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1008 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1009 if (rbs != 1 || cbs != 1) { 1010 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1011 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1012 } else { 1013 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1014 } 1015 if (mat->factortype) { 1016 MatSolverType solver; 1017 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1018 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1019 } 1020 if (mat->ops->getinfo) { 1021 MatInfo info; 1022 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1023 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1024 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1025 } 1026 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1027 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1028 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1029 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1030 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1031 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1032 } 1033 #if defined(PETSC_HAVE_SAWS) 1034 } else if (issaws) { 1035 PetscMPIInt rank; 1036 1037 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1038 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1039 if (!((PetscObject)mat)->amsmem && !rank) { 1040 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1041 } 1042 #endif 1043 } else if (isstring) { 1044 const char *type; 1045 ierr = MatGetType(mat,&type);CHKERRQ(ierr); 1046 ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr); 1047 if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);} 1048 } 1049 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1050 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1051 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1052 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1053 } else if (mat->ops->view) { 1054 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1055 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1056 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1057 } 1058 if (iascii) { 1059 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1060 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1061 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1062 } 1063 } 1064 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1065 PetscFunctionReturn(0); 1066 } 1067 1068 #if defined(PETSC_USE_DEBUG) 1069 #include <../src/sys/totalview/tv_data_display.h> 1070 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1071 { 1072 TV_add_row("Local rows", "int", &mat->rmap->n); 1073 TV_add_row("Local columns", "int", &mat->cmap->n); 1074 TV_add_row("Global rows", "int", &mat->rmap->N); 1075 TV_add_row("Global columns", "int", &mat->cmap->N); 1076 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1077 return TV_format_OK; 1078 } 1079 #endif 1080 1081 /*@C 1082 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1083 with MatView(). The matrix format is determined from the options database. 1084 Generates a parallel MPI matrix if the communicator has more than one 1085 processor. The default matrix type is AIJ. 1086 1087 Collective on PetscViewer 1088 1089 Input Parameters: 1090 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1091 or some related function before a call to MatLoad() 1092 - viewer - binary/HDF5 file viewer 1093 1094 Options Database Keys: 1095 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1096 block size 1097 . -matload_block_size <bs> 1098 1099 Level: beginner 1100 1101 Notes: 1102 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1103 Mat before calling this routine if you wish to set it from the options database. 1104 1105 MatLoad() automatically loads into the options database any options 1106 given in the file filename.info where filename is the name of the file 1107 that was passed to the PetscViewerBinaryOpen(). The options in the info 1108 file will be ignored if you use the -viewer_binary_skip_info option. 1109 1110 If the type or size of newmat is not set before a call to MatLoad, PETSc 1111 sets the default matrix type AIJ and sets the local and global sizes. 1112 If type and/or size is already set, then the same are used. 1113 1114 In parallel, each processor can load a subset of rows (or the 1115 entire matrix). This routine is especially useful when a large 1116 matrix is stored on disk and only part of it is desired on each 1117 processor. For example, a parallel solver may access only some of 1118 the rows from each processor. The algorithm used here reads 1119 relatively small blocks of data rather than reading the entire 1120 matrix and then subsetting it. 1121 1122 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1123 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1124 or the sequence like 1125 $ PetscViewer v; 1126 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1127 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1128 $ PetscViewerSetFromOptions(v); 1129 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1130 $ PetscViewerFileSetName(v,"datafile"); 1131 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1132 $ -viewer_type {binary,hdf5} 1133 1134 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1135 and src/mat/examples/tutorials/ex10.c with the second approach. 1136 1137 Notes about the PETSc binary format: 1138 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1139 is read onto rank 0 and then shipped to its destination rank, one after another. 1140 Multiple objects, both matrices and vectors, can be stored within the same file. 1141 Their PetscObject name is ignored; they are loaded in the order of their storage. 1142 1143 Most users should not need to know the details of the binary storage 1144 format, since MatLoad() and MatView() completely hide these details. 1145 But for anyone who's interested, the standard binary matrix storage 1146 format is 1147 1148 $ int MAT_FILE_CLASSID 1149 $ int number of rows 1150 $ int number of columns 1151 $ int total number of nonzeros 1152 $ int *number nonzeros in each row 1153 $ int *column indices of all nonzeros (starting index is zero) 1154 $ PetscScalar *values of all nonzeros 1155 1156 PETSc automatically does the byte swapping for 1157 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1158 linux, Windows and the paragon; thus if you write your own binary 1159 read/write routines you have to swap the bytes; see PetscBinaryRead() 1160 and PetscBinaryWrite() to see how this may be done. 1161 1162 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1163 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1164 Each processor's chunk is loaded independently by its owning rank. 1165 Multiple objects, both matrices and vectors, can be stored within the same file. 1166 They are looked up by their PetscObject name. 1167 1168 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1169 by default the same structure and naming of the AIJ arrays and column count 1170 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1171 $ save example.mat A b -v7.3 1172 can be directly read by this routine (see Reference 1 for details). 1173 Note that depending on your MATLAB version, this format might be a default, 1174 otherwise you can set it as default in Preferences. 1175 1176 Unless -nocompression flag is used to save the file in MATLAB, 1177 PETSc must be configured with ZLIB package. 1178 1179 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1180 1181 Current HDF5 (MAT-File) limitations: 1182 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1183 1184 Corresponding MatView() is not yet implemented. 1185 1186 The loaded matrix is actually a transpose of the original one in MATLAB, 1187 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1188 With this format, matrix is automatically transposed by PETSc, 1189 unless the matrix is marked as SPD or symmetric 1190 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1191 1192 References: 1193 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1194 1195 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1196 1197 @*/ 1198 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1199 { 1200 PetscErrorCode ierr; 1201 PetscBool flg; 1202 1203 PetscFunctionBegin; 1204 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1205 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1206 1207 if (!((PetscObject)newmat)->type_name) { 1208 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1209 } 1210 1211 flg = PETSC_FALSE; 1212 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1213 if (flg) { 1214 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1215 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1216 } 1217 flg = PETSC_FALSE; 1218 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1219 if (flg) { 1220 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1221 } 1222 1223 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1224 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1225 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1226 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1227 PetscFunctionReturn(0); 1228 } 1229 1230 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1231 { 1232 PetscErrorCode ierr; 1233 Mat_Redundant *redund = *redundant; 1234 PetscInt i; 1235 1236 PetscFunctionBegin; 1237 if (redund){ 1238 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1239 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1240 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1241 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1242 } else { 1243 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1244 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1245 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1246 for (i=0; i<redund->nrecvs; i++) { 1247 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1248 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1249 } 1250 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1251 } 1252 1253 if (redund->subcomm) { 1254 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1255 } 1256 ierr = PetscFree(redund);CHKERRQ(ierr); 1257 } 1258 PetscFunctionReturn(0); 1259 } 1260 1261 /*@ 1262 MatDestroy - Frees space taken by a matrix. 1263 1264 Collective on Mat 1265 1266 Input Parameter: 1267 . A - the matrix 1268 1269 Level: beginner 1270 1271 @*/ 1272 PetscErrorCode MatDestroy(Mat *A) 1273 { 1274 PetscErrorCode ierr; 1275 1276 PetscFunctionBegin; 1277 if (!*A) PetscFunctionReturn(0); 1278 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1279 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1280 1281 /* if memory was published with SAWs then destroy it */ 1282 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1283 if ((*A)->ops->destroy) { 1284 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1285 } 1286 1287 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1288 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1289 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1290 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1291 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1292 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1293 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1294 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1295 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1296 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1297 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1298 PetscFunctionReturn(0); 1299 } 1300 1301 /*@C 1302 MatSetValues - Inserts or adds a block of values into a matrix. 1303 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1304 MUST be called after all calls to MatSetValues() have been completed. 1305 1306 Not Collective 1307 1308 Input Parameters: 1309 + mat - the matrix 1310 . v - a logically two-dimensional array of values 1311 . m, idxm - the number of rows and their global indices 1312 . n, idxn - the number of columns and their global indices 1313 - addv - either ADD_VALUES or INSERT_VALUES, where 1314 ADD_VALUES adds values to any existing entries, and 1315 INSERT_VALUES replaces existing entries with new values 1316 1317 Notes: 1318 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1319 MatSetUp() before using this routine 1320 1321 By default the values, v, are row-oriented. See MatSetOption() for other options. 1322 1323 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1324 options cannot be mixed without intervening calls to the assembly 1325 routines. 1326 1327 MatSetValues() uses 0-based row and column numbers in Fortran 1328 as well as in C. 1329 1330 Negative indices may be passed in idxm and idxn, these rows and columns are 1331 simply ignored. This allows easily inserting element stiffness matrices 1332 with homogeneous Dirchlet boundary conditions that you don't want represented 1333 in the matrix. 1334 1335 Efficiency Alert: 1336 The routine MatSetValuesBlocked() may offer much better efficiency 1337 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1338 1339 Level: beginner 1340 1341 Developer Notes: 1342 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1343 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1344 1345 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1346 InsertMode, INSERT_VALUES, ADD_VALUES 1347 @*/ 1348 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1349 { 1350 PetscErrorCode ierr; 1351 #if defined(PETSC_USE_DEBUG) 1352 PetscInt i,j; 1353 #endif 1354 1355 PetscFunctionBeginHot; 1356 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1357 PetscValidType(mat,1); 1358 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1359 PetscValidIntPointer(idxm,3); 1360 PetscValidIntPointer(idxn,5); 1361 MatCheckPreallocated(mat,1); 1362 1363 if (mat->insertmode == NOT_SET_VALUES) { 1364 mat->insertmode = addv; 1365 } 1366 #if defined(PETSC_USE_DEBUG) 1367 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1368 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1369 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1370 1371 for (i=0; i<m; i++) { 1372 for (j=0; j<n; j++) { 1373 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1374 #if defined(PETSC_USE_COMPLEX) 1375 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]); 1376 #else 1377 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1378 #endif 1379 } 1380 } 1381 #endif 1382 1383 if (mat->assembled) { 1384 mat->was_assembled = PETSC_TRUE; 1385 mat->assembled = PETSC_FALSE; 1386 } 1387 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1388 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1389 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1390 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1391 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1392 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1393 } 1394 #endif 1395 PetscFunctionReturn(0); 1396 } 1397 1398 1399 /*@ 1400 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1401 values into a matrix 1402 1403 Not Collective 1404 1405 Input Parameters: 1406 + mat - the matrix 1407 . row - the (block) row to set 1408 - v - a logically two-dimensional array of values 1409 1410 Notes: 1411 By the values, v, are column-oriented (for the block version) and sorted 1412 1413 All the nonzeros in the row must be provided 1414 1415 The matrix must have previously had its column indices set 1416 1417 The row must belong to this process 1418 1419 Level: intermediate 1420 1421 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1422 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1423 @*/ 1424 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1425 { 1426 PetscErrorCode ierr; 1427 PetscInt globalrow; 1428 1429 PetscFunctionBegin; 1430 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1431 PetscValidType(mat,1); 1432 PetscValidScalarPointer(v,2); 1433 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1434 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1435 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1436 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1437 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1438 } 1439 #endif 1440 PetscFunctionReturn(0); 1441 } 1442 1443 /*@ 1444 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1445 values into a matrix 1446 1447 Not Collective 1448 1449 Input Parameters: 1450 + mat - the matrix 1451 . row - the (block) row to set 1452 - 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 1453 1454 Notes: 1455 The values, v, are column-oriented for the block version. 1456 1457 All the nonzeros in the row must be provided 1458 1459 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1460 1461 The row must belong to this process 1462 1463 Level: advanced 1464 1465 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1466 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1467 @*/ 1468 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1469 { 1470 PetscErrorCode ierr; 1471 1472 PetscFunctionBeginHot; 1473 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1474 PetscValidType(mat,1); 1475 MatCheckPreallocated(mat,1); 1476 PetscValidScalarPointer(v,2); 1477 #if defined(PETSC_USE_DEBUG) 1478 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1479 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1480 #endif 1481 mat->insertmode = INSERT_VALUES; 1482 1483 if (mat->assembled) { 1484 mat->was_assembled = PETSC_TRUE; 1485 mat->assembled = PETSC_FALSE; 1486 } 1487 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1488 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1489 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1490 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1491 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1492 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1493 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1494 } 1495 #endif 1496 PetscFunctionReturn(0); 1497 } 1498 1499 /*@ 1500 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1501 Using structured grid indexing 1502 1503 Not Collective 1504 1505 Input Parameters: 1506 + mat - the matrix 1507 . m - number of rows being entered 1508 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1509 . n - number of columns being entered 1510 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1511 . v - a logically two-dimensional array of values 1512 - addv - either ADD_VALUES or INSERT_VALUES, where 1513 ADD_VALUES adds values to any existing entries, and 1514 INSERT_VALUES replaces existing entries with new values 1515 1516 Notes: 1517 By default the values, v, are row-oriented. See MatSetOption() for other options. 1518 1519 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1520 options cannot be mixed without intervening calls to the assembly 1521 routines. 1522 1523 The grid coordinates are across the entire grid, not just the local portion 1524 1525 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1526 as well as in C. 1527 1528 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1529 1530 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1531 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1532 1533 The columns and rows in the stencil passed in MUST be contained within the 1534 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1535 if you create a DMDA with an overlap of one grid level and on a particular process its first 1536 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1537 first i index you can use in your column and row indices in MatSetStencil() is 5. 1538 1539 In Fortran idxm and idxn should be declared as 1540 $ MatStencil idxm(4,m),idxn(4,n) 1541 and the values inserted using 1542 $ idxm(MatStencil_i,1) = i 1543 $ idxm(MatStencil_j,1) = j 1544 $ idxm(MatStencil_k,1) = k 1545 $ idxm(MatStencil_c,1) = c 1546 etc 1547 1548 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1549 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1550 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1551 DM_BOUNDARY_PERIODIC boundary type. 1552 1553 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 1554 a single value per point) you can skip filling those indices. 1555 1556 Inspired by the structured grid interface to the HYPRE package 1557 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1558 1559 Efficiency Alert: 1560 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1561 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1562 1563 Level: beginner 1564 1565 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1566 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1567 @*/ 1568 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1569 { 1570 PetscErrorCode ierr; 1571 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1572 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1573 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1574 1575 PetscFunctionBegin; 1576 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1577 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1578 PetscValidType(mat,1); 1579 PetscValidIntPointer(idxm,3); 1580 PetscValidIntPointer(idxn,5); 1581 1582 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1583 jdxm = buf; jdxn = buf+m; 1584 } else { 1585 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1586 jdxm = bufm; jdxn = bufn; 1587 } 1588 for (i=0; i<m; i++) { 1589 for (j=0; j<3-sdim; j++) dxm++; 1590 tmp = *dxm++ - starts[0]; 1591 for (j=0; j<dim-1; j++) { 1592 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1593 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1594 } 1595 if (mat->stencil.noc) dxm++; 1596 jdxm[i] = tmp; 1597 } 1598 for (i=0; i<n; i++) { 1599 for (j=0; j<3-sdim; j++) dxn++; 1600 tmp = *dxn++ - starts[0]; 1601 for (j=0; j<dim-1; j++) { 1602 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1603 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1604 } 1605 if (mat->stencil.noc) dxn++; 1606 jdxn[i] = tmp; 1607 } 1608 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1609 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1610 PetscFunctionReturn(0); 1611 } 1612 1613 /*@ 1614 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1615 Using structured grid indexing 1616 1617 Not Collective 1618 1619 Input Parameters: 1620 + mat - the matrix 1621 . m - number of rows being entered 1622 . idxm - grid coordinates for matrix rows being entered 1623 . n - number of columns being entered 1624 . idxn - grid coordinates for matrix columns being entered 1625 . v - a logically two-dimensional array of values 1626 - addv - either ADD_VALUES or INSERT_VALUES, where 1627 ADD_VALUES adds values to any existing entries, and 1628 INSERT_VALUES replaces existing entries with new values 1629 1630 Notes: 1631 By default the values, v, are row-oriented and unsorted. 1632 See MatSetOption() for other options. 1633 1634 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1635 options cannot be mixed without intervening calls to the assembly 1636 routines. 1637 1638 The grid coordinates are across the entire grid, not just the local portion 1639 1640 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1641 as well as in C. 1642 1643 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1644 1645 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1646 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1647 1648 The columns and rows in the stencil passed in MUST be contained within the 1649 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1650 if you create a DMDA with an overlap of one grid level and on a particular process its first 1651 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1652 first i index you can use in your column and row indices in MatSetStencil() is 5. 1653 1654 In Fortran idxm and idxn should be declared as 1655 $ MatStencil idxm(4,m),idxn(4,n) 1656 and the values inserted using 1657 $ idxm(MatStencil_i,1) = i 1658 $ idxm(MatStencil_j,1) = j 1659 $ idxm(MatStencil_k,1) = k 1660 etc 1661 1662 Negative indices may be passed in idxm and idxn, these rows and columns are 1663 simply ignored. This allows easily inserting element stiffness matrices 1664 with homogeneous Dirchlet boundary conditions that you don't want represented 1665 in the matrix. 1666 1667 Inspired by the structured grid interface to the HYPRE package 1668 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1669 1670 Level: beginner 1671 1672 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1673 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1674 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1675 @*/ 1676 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1677 { 1678 PetscErrorCode ierr; 1679 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1680 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1681 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1682 1683 PetscFunctionBegin; 1684 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1685 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1686 PetscValidType(mat,1); 1687 PetscValidIntPointer(idxm,3); 1688 PetscValidIntPointer(idxn,5); 1689 PetscValidScalarPointer(v,6); 1690 1691 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1692 jdxm = buf; jdxn = buf+m; 1693 } else { 1694 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1695 jdxm = bufm; jdxn = bufn; 1696 } 1697 for (i=0; i<m; i++) { 1698 for (j=0; j<3-sdim; j++) dxm++; 1699 tmp = *dxm++ - starts[0]; 1700 for (j=0; j<sdim-1; j++) { 1701 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1702 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1703 } 1704 dxm++; 1705 jdxm[i] = tmp; 1706 } 1707 for (i=0; i<n; i++) { 1708 for (j=0; j<3-sdim; j++) dxn++; 1709 tmp = *dxn++ - starts[0]; 1710 for (j=0; j<sdim-1; j++) { 1711 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1712 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1713 } 1714 dxn++; 1715 jdxn[i] = tmp; 1716 } 1717 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1718 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1719 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1720 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1721 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1722 } 1723 #endif 1724 PetscFunctionReturn(0); 1725 } 1726 1727 /*@ 1728 MatSetStencil - Sets the grid information for setting values into a matrix via 1729 MatSetValuesStencil() 1730 1731 Not Collective 1732 1733 Input Parameters: 1734 + mat - the matrix 1735 . dim - dimension of the grid 1, 2, or 3 1736 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1737 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1738 - dof - number of degrees of freedom per node 1739 1740 1741 Inspired by the structured grid interface to the HYPRE package 1742 (www.llnl.gov/CASC/hyper) 1743 1744 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1745 user. 1746 1747 Level: beginner 1748 1749 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1750 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1751 @*/ 1752 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1753 { 1754 PetscInt i; 1755 1756 PetscFunctionBegin; 1757 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1758 PetscValidIntPointer(dims,3); 1759 PetscValidIntPointer(starts,4); 1760 1761 mat->stencil.dim = dim + (dof > 1); 1762 for (i=0; i<dim; i++) { 1763 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1764 mat->stencil.starts[i] = starts[dim-i-1]; 1765 } 1766 mat->stencil.dims[dim] = dof; 1767 mat->stencil.starts[dim] = 0; 1768 mat->stencil.noc = (PetscBool)(dof == 1); 1769 PetscFunctionReturn(0); 1770 } 1771 1772 /*@C 1773 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1774 1775 Not Collective 1776 1777 Input Parameters: 1778 + mat - the matrix 1779 . v - a logically two-dimensional array of values 1780 . m, idxm - the number of block rows and their global block indices 1781 . n, idxn - the number of block columns and their global block indices 1782 - addv - either ADD_VALUES or INSERT_VALUES, where 1783 ADD_VALUES adds values to any existing entries, and 1784 INSERT_VALUES replaces existing entries with new values 1785 1786 Notes: 1787 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1788 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1789 1790 The m and n count the NUMBER of blocks in the row direction and column direction, 1791 NOT the total number of rows/columns; for example, if the block size is 2 and 1792 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1793 The values in idxm would be 1 2; that is the first index for each block divided by 1794 the block size. 1795 1796 Note that you must call MatSetBlockSize() when constructing this matrix (before 1797 preallocating it). 1798 1799 By default the values, v, are row-oriented, so the layout of 1800 v is the same as for MatSetValues(). See MatSetOption() for other options. 1801 1802 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1803 options cannot be mixed without intervening calls to the assembly 1804 routines. 1805 1806 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1807 as well as in C. 1808 1809 Negative indices may be passed in idxm and idxn, these rows and columns are 1810 simply ignored. This allows easily inserting element stiffness matrices 1811 with homogeneous Dirchlet boundary conditions that you don't want represented 1812 in the matrix. 1813 1814 Each time an entry is set within a sparse matrix via MatSetValues(), 1815 internal searching must be done to determine where to place the 1816 data in the matrix storage space. By instead inserting blocks of 1817 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1818 reduced. 1819 1820 Example: 1821 $ Suppose m=n=2 and block size(bs) = 2 The array is 1822 $ 1823 $ 1 2 | 3 4 1824 $ 5 6 | 7 8 1825 $ - - - | - - - 1826 $ 9 10 | 11 12 1827 $ 13 14 | 15 16 1828 $ 1829 $ v[] should be passed in like 1830 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1831 $ 1832 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1833 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1834 1835 Level: intermediate 1836 1837 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1838 @*/ 1839 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1840 { 1841 PetscErrorCode ierr; 1842 1843 PetscFunctionBeginHot; 1844 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1845 PetscValidType(mat,1); 1846 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1847 PetscValidIntPointer(idxm,3); 1848 PetscValidIntPointer(idxn,5); 1849 PetscValidScalarPointer(v,6); 1850 MatCheckPreallocated(mat,1); 1851 if (mat->insertmode == NOT_SET_VALUES) { 1852 mat->insertmode = addv; 1853 } 1854 #if defined(PETSC_USE_DEBUG) 1855 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1856 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1857 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1858 #endif 1859 1860 if (mat->assembled) { 1861 mat->was_assembled = PETSC_TRUE; 1862 mat->assembled = PETSC_FALSE; 1863 } 1864 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1865 if (mat->ops->setvaluesblocked) { 1866 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1867 } else { 1868 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1869 PetscInt i,j,bs,cbs; 1870 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1871 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1872 iidxm = buf; iidxn = buf + m*bs; 1873 } else { 1874 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1875 iidxm = bufr; iidxn = bufc; 1876 } 1877 for (i=0; i<m; i++) { 1878 for (j=0; j<bs; j++) { 1879 iidxm[i*bs+j] = bs*idxm[i] + j; 1880 } 1881 } 1882 for (i=0; i<n; i++) { 1883 for (j=0; j<cbs; j++) { 1884 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1885 } 1886 } 1887 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1888 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1889 } 1890 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1891 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1892 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1893 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1894 } 1895 #endif 1896 PetscFunctionReturn(0); 1897 } 1898 1899 /*@ 1900 MatGetValues - Gets a block of values from a matrix. 1901 1902 Not Collective; currently only returns a local block 1903 1904 Input Parameters: 1905 + mat - the matrix 1906 . v - a logically two-dimensional array for storing the values 1907 . m, idxm - the number of rows and their global indices 1908 - n, idxn - the number of columns and their global indices 1909 1910 Notes: 1911 The user must allocate space (m*n PetscScalars) for the values, v. 1912 The values, v, are then returned in a row-oriented format, 1913 analogous to that used by default in MatSetValues(). 1914 1915 MatGetValues() uses 0-based row and column numbers in 1916 Fortran as well as in C. 1917 1918 MatGetValues() requires that the matrix has been assembled 1919 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1920 MatSetValues() and MatGetValues() CANNOT be made in succession 1921 without intermediate matrix assembly. 1922 1923 Negative row or column indices will be ignored and those locations in v[] will be 1924 left unchanged. 1925 1926 Level: advanced 1927 1928 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1929 @*/ 1930 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1931 { 1932 PetscErrorCode ierr; 1933 1934 PetscFunctionBegin; 1935 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1936 PetscValidType(mat,1); 1937 if (!m || !n) PetscFunctionReturn(0); 1938 PetscValidIntPointer(idxm,3); 1939 PetscValidIntPointer(idxn,5); 1940 PetscValidScalarPointer(v,6); 1941 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1942 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1943 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1944 MatCheckPreallocated(mat,1); 1945 1946 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1947 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1948 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1949 PetscFunctionReturn(0); 1950 } 1951 1952 /*@ 1953 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1954 the same size. Currently, this can only be called once and creates the given matrix. 1955 1956 Not Collective 1957 1958 Input Parameters: 1959 + mat - the matrix 1960 . nb - the number of blocks 1961 . bs - the number of rows (and columns) in each block 1962 . rows - a concatenation of the rows for each block 1963 - v - a concatenation of logically two-dimensional arrays of values 1964 1965 Notes: 1966 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1967 1968 Level: advanced 1969 1970 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1971 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1972 @*/ 1973 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1974 { 1975 PetscErrorCode ierr; 1976 1977 PetscFunctionBegin; 1978 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1979 PetscValidType(mat,1); 1980 PetscValidScalarPointer(rows,4); 1981 PetscValidScalarPointer(v,5); 1982 #if defined(PETSC_USE_DEBUG) 1983 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1984 #endif 1985 1986 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1987 if (mat->ops->setvaluesbatch) { 1988 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1989 } else { 1990 PetscInt b; 1991 for (b = 0; b < nb; ++b) { 1992 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1993 } 1994 } 1995 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1996 PetscFunctionReturn(0); 1997 } 1998 1999 /*@ 2000 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2001 the routine MatSetValuesLocal() to allow users to insert matrix entries 2002 using a local (per-processor) numbering. 2003 2004 Not Collective 2005 2006 Input Parameters: 2007 + x - the matrix 2008 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2009 - cmapping - column mapping 2010 2011 Level: intermediate 2012 2013 2014 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 2015 @*/ 2016 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2017 { 2018 PetscErrorCode ierr; 2019 2020 PetscFunctionBegin; 2021 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2022 PetscValidType(x,1); 2023 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2024 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2025 2026 if (x->ops->setlocaltoglobalmapping) { 2027 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2028 } else { 2029 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2030 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2031 } 2032 PetscFunctionReturn(0); 2033 } 2034 2035 2036 /*@ 2037 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2038 2039 Not Collective 2040 2041 Input Parameters: 2042 . A - the matrix 2043 2044 Output Parameters: 2045 + rmapping - row mapping 2046 - cmapping - column mapping 2047 2048 Level: advanced 2049 2050 2051 .seealso: MatSetValuesLocal() 2052 @*/ 2053 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2054 { 2055 PetscFunctionBegin; 2056 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2057 PetscValidType(A,1); 2058 if (rmapping) PetscValidPointer(rmapping,2); 2059 if (cmapping) PetscValidPointer(cmapping,3); 2060 if (rmapping) *rmapping = A->rmap->mapping; 2061 if (cmapping) *cmapping = A->cmap->mapping; 2062 PetscFunctionReturn(0); 2063 } 2064 2065 /*@ 2066 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2067 2068 Not Collective 2069 2070 Input Parameters: 2071 . A - the matrix 2072 2073 Output Parameters: 2074 + rmap - row layout 2075 - cmap - column layout 2076 2077 Level: advanced 2078 2079 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2080 @*/ 2081 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2082 { 2083 PetscFunctionBegin; 2084 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2085 PetscValidType(A,1); 2086 if (rmap) PetscValidPointer(rmap,2); 2087 if (cmap) PetscValidPointer(cmap,3); 2088 if (rmap) *rmap = A->rmap; 2089 if (cmap) *cmap = A->cmap; 2090 PetscFunctionReturn(0); 2091 } 2092 2093 /*@C 2094 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2095 using a local ordering of the nodes. 2096 2097 Not Collective 2098 2099 Input Parameters: 2100 + mat - the matrix 2101 . nrow, irow - number of rows and their local indices 2102 . ncol, icol - number of columns and their local indices 2103 . y - a logically two-dimensional array of values 2104 - addv - either INSERT_VALUES or ADD_VALUES, where 2105 ADD_VALUES adds values to any existing entries, and 2106 INSERT_VALUES replaces existing entries with new values 2107 2108 Notes: 2109 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2110 MatSetUp() before using this routine 2111 2112 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2113 2114 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2115 options cannot be mixed without intervening calls to the assembly 2116 routines. 2117 2118 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2119 MUST be called after all calls to MatSetValuesLocal() have been completed. 2120 2121 Level: intermediate 2122 2123 Developer Notes: 2124 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2125 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2126 2127 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2128 MatSetValueLocal() 2129 @*/ 2130 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2131 { 2132 PetscErrorCode ierr; 2133 2134 PetscFunctionBeginHot; 2135 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2136 PetscValidType(mat,1); 2137 MatCheckPreallocated(mat,1); 2138 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2139 PetscValidIntPointer(irow,3); 2140 PetscValidIntPointer(icol,5); 2141 if (mat->insertmode == NOT_SET_VALUES) { 2142 mat->insertmode = addv; 2143 } 2144 #if defined(PETSC_USE_DEBUG) 2145 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2146 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2147 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2148 #endif 2149 2150 if (mat->assembled) { 2151 mat->was_assembled = PETSC_TRUE; 2152 mat->assembled = PETSC_FALSE; 2153 } 2154 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2155 if (mat->ops->setvalueslocal) { 2156 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2157 } else { 2158 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2159 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2160 irowm = buf; icolm = buf+nrow; 2161 } else { 2162 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2163 irowm = bufr; icolm = bufc; 2164 } 2165 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2166 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2167 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2168 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2169 } 2170 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2171 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2172 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2173 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2174 } 2175 #endif 2176 PetscFunctionReturn(0); 2177 } 2178 2179 /*@C 2180 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2181 using a local ordering of the nodes a block at a time. 2182 2183 Not Collective 2184 2185 Input Parameters: 2186 + x - the matrix 2187 . nrow, irow - number of rows and their local indices 2188 . ncol, icol - number of columns and their local indices 2189 . y - a logically two-dimensional array of values 2190 - addv - either INSERT_VALUES or ADD_VALUES, where 2191 ADD_VALUES adds values to any existing entries, and 2192 INSERT_VALUES replaces existing entries with new values 2193 2194 Notes: 2195 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2196 MatSetUp() before using this routine 2197 2198 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2199 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2200 2201 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2202 options cannot be mixed without intervening calls to the assembly 2203 routines. 2204 2205 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2206 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2207 2208 Level: intermediate 2209 2210 Developer Notes: 2211 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2212 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2213 2214 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2215 MatSetValuesLocal(), MatSetValuesBlocked() 2216 @*/ 2217 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2218 { 2219 PetscErrorCode ierr; 2220 2221 PetscFunctionBeginHot; 2222 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2223 PetscValidType(mat,1); 2224 MatCheckPreallocated(mat,1); 2225 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2226 PetscValidIntPointer(irow,3); 2227 PetscValidIntPointer(icol,5); 2228 PetscValidScalarPointer(y,6); 2229 if (mat->insertmode == NOT_SET_VALUES) { 2230 mat->insertmode = addv; 2231 } 2232 #if defined(PETSC_USE_DEBUG) 2233 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2234 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2235 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); 2236 #endif 2237 2238 if (mat->assembled) { 2239 mat->was_assembled = PETSC_TRUE; 2240 mat->assembled = PETSC_FALSE; 2241 } 2242 #if defined(PETSC_USE_DEBUG) 2243 /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2244 if (mat->rmap->mapping) { 2245 PetscInt irbs, rbs; 2246 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2247 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2248 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs); 2249 } 2250 if (mat->cmap->mapping) { 2251 PetscInt icbs, cbs; 2252 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2253 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2254 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs); 2255 } 2256 #endif 2257 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2258 if (mat->ops->setvaluesblockedlocal) { 2259 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2260 } else { 2261 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2262 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2263 irowm = buf; icolm = buf + nrow; 2264 } else { 2265 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2266 irowm = bufr; icolm = bufc; 2267 } 2268 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2269 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2270 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2271 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2272 } 2273 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2274 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2275 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2276 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2277 } 2278 #endif 2279 PetscFunctionReturn(0); 2280 } 2281 2282 /*@ 2283 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2284 2285 Collective on Mat 2286 2287 Input Parameters: 2288 + mat - the matrix 2289 - x - the vector to be multiplied 2290 2291 Output Parameters: 2292 . y - the result 2293 2294 Notes: 2295 The vectors x and y cannot be the same. I.e., one cannot 2296 call MatMult(A,y,y). 2297 2298 Level: developer 2299 2300 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2301 @*/ 2302 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2303 { 2304 PetscErrorCode ierr; 2305 2306 PetscFunctionBegin; 2307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2308 PetscValidType(mat,1); 2309 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2310 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2311 2312 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2313 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2314 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2315 MatCheckPreallocated(mat,1); 2316 2317 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2318 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2319 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2320 PetscFunctionReturn(0); 2321 } 2322 2323 /* --------------------------------------------------------*/ 2324 /*@ 2325 MatMult - Computes the matrix-vector product, y = Ax. 2326 2327 Neighbor-wise Collective on Mat 2328 2329 Input Parameters: 2330 + mat - the matrix 2331 - x - the vector to be multiplied 2332 2333 Output Parameters: 2334 . y - the result 2335 2336 Notes: 2337 The vectors x and y cannot be the same. I.e., one cannot 2338 call MatMult(A,y,y). 2339 2340 Level: beginner 2341 2342 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2343 @*/ 2344 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2345 { 2346 PetscErrorCode ierr; 2347 2348 PetscFunctionBegin; 2349 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2350 PetscValidType(mat,1); 2351 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2352 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2353 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2354 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2355 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2356 #if !defined(PETSC_HAVE_CONSTRAINTS) 2357 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); 2358 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); 2359 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); 2360 #endif 2361 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2362 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2363 MatCheckPreallocated(mat,1); 2364 2365 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2366 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2367 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2368 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2369 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2370 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2371 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2372 PetscFunctionReturn(0); 2373 } 2374 2375 /*@ 2376 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2377 2378 Neighbor-wise Collective on Mat 2379 2380 Input Parameters: 2381 + mat - the matrix 2382 - x - the vector to be multiplied 2383 2384 Output Parameters: 2385 . y - the result 2386 2387 Notes: 2388 The vectors x and y cannot be the same. I.e., one cannot 2389 call MatMultTranspose(A,y,y). 2390 2391 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2392 use MatMultHermitianTranspose() 2393 2394 Level: beginner 2395 2396 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2397 @*/ 2398 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2399 { 2400 PetscErrorCode ierr; 2401 2402 PetscFunctionBegin; 2403 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2404 PetscValidType(mat,1); 2405 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2406 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2407 2408 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2409 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2410 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2411 #if !defined(PETSC_HAVE_CONSTRAINTS) 2412 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); 2413 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); 2414 #endif 2415 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2416 MatCheckPreallocated(mat,1); 2417 2418 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2419 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2420 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2421 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2422 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2423 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2424 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2425 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2426 PetscFunctionReturn(0); 2427 } 2428 2429 /*@ 2430 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2431 2432 Neighbor-wise Collective on Mat 2433 2434 Input Parameters: 2435 + mat - the matrix 2436 - x - the vector to be multilplied 2437 2438 Output Parameters: 2439 . y - the result 2440 2441 Notes: 2442 The vectors x and y cannot be the same. I.e., one cannot 2443 call MatMultHermitianTranspose(A,y,y). 2444 2445 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2446 2447 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2448 2449 Level: beginner 2450 2451 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2452 @*/ 2453 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2454 { 2455 PetscErrorCode ierr; 2456 Vec w; 2457 2458 PetscFunctionBegin; 2459 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2460 PetscValidType(mat,1); 2461 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2462 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2463 2464 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2465 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2466 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2467 #if !defined(PETSC_HAVE_CONSTRAINTS) 2468 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 2469 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 2470 #endif 2471 MatCheckPreallocated(mat,1); 2472 2473 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2474 if (mat->ops->multhermitiantranspose) { 2475 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2476 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2477 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2478 } else { 2479 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2480 ierr = VecCopy(x,w);CHKERRQ(ierr); 2481 ierr = VecConjugate(w);CHKERRQ(ierr); 2482 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2483 ierr = VecDestroy(&w);CHKERRQ(ierr); 2484 ierr = VecConjugate(y);CHKERRQ(ierr); 2485 } 2486 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2487 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2488 PetscFunctionReturn(0); 2489 } 2490 2491 /*@ 2492 MatMultAdd - Computes v3 = v2 + A * v1. 2493 2494 Neighbor-wise Collective on Mat 2495 2496 Input Parameters: 2497 + mat - the matrix 2498 - v1, v2 - the vectors 2499 2500 Output Parameters: 2501 . v3 - the result 2502 2503 Notes: 2504 The vectors v1 and v3 cannot be the same. I.e., one cannot 2505 call MatMultAdd(A,v1,v2,v1). 2506 2507 Level: beginner 2508 2509 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2510 @*/ 2511 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2512 { 2513 PetscErrorCode ierr; 2514 2515 PetscFunctionBegin; 2516 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2517 PetscValidType(mat,1); 2518 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2519 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2520 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2521 2522 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2523 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2524 if (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); 2525 /* 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); 2526 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); */ 2527 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); 2528 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); 2529 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2530 MatCheckPreallocated(mat,1); 2531 2532 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2533 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2534 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2535 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2536 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2537 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2538 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2539 PetscFunctionReturn(0); 2540 } 2541 2542 /*@ 2543 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2544 2545 Neighbor-wise Collective on Mat 2546 2547 Input Parameters: 2548 + mat - the matrix 2549 - v1, v2 - the vectors 2550 2551 Output Parameters: 2552 . v3 - the result 2553 2554 Notes: 2555 The vectors v1 and v3 cannot be the same. I.e., one cannot 2556 call MatMultTransposeAdd(A,v1,v2,v1). 2557 2558 Level: beginner 2559 2560 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2561 @*/ 2562 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2563 { 2564 PetscErrorCode ierr; 2565 2566 PetscFunctionBegin; 2567 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2568 PetscValidType(mat,1); 2569 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2570 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2571 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2572 2573 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2574 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2575 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2576 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2577 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); 2578 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); 2579 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); 2580 MatCheckPreallocated(mat,1); 2581 2582 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2583 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2584 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2585 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2586 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2587 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2588 PetscFunctionReturn(0); 2589 } 2590 2591 /*@ 2592 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2593 2594 Neighbor-wise Collective on Mat 2595 2596 Input Parameters: 2597 + mat - the matrix 2598 - v1, v2 - the vectors 2599 2600 Output Parameters: 2601 . v3 - the result 2602 2603 Notes: 2604 The vectors v1 and v3 cannot be the same. I.e., one cannot 2605 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2606 2607 Level: beginner 2608 2609 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2610 @*/ 2611 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2612 { 2613 PetscErrorCode ierr; 2614 2615 PetscFunctionBegin; 2616 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2617 PetscValidType(mat,1); 2618 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2619 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2620 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2621 2622 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2623 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2624 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2625 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); 2626 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); 2627 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); 2628 MatCheckPreallocated(mat,1); 2629 2630 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2631 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2632 if (mat->ops->multhermitiantransposeadd) { 2633 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2634 } else { 2635 Vec w,z; 2636 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2637 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2638 ierr = VecConjugate(w);CHKERRQ(ierr); 2639 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2640 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2641 ierr = VecDestroy(&w);CHKERRQ(ierr); 2642 ierr = VecConjugate(z);CHKERRQ(ierr); 2643 if (v2 != v3) { 2644 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2645 } else { 2646 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2647 } 2648 ierr = VecDestroy(&z);CHKERRQ(ierr); 2649 } 2650 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2651 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2652 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2653 PetscFunctionReturn(0); 2654 } 2655 2656 /*@ 2657 MatMultConstrained - The inner multiplication routine for a 2658 constrained matrix P^T A P. 2659 2660 Neighbor-wise Collective on Mat 2661 2662 Input Parameters: 2663 + mat - the matrix 2664 - x - the vector to be multilplied 2665 2666 Output Parameters: 2667 . y - the result 2668 2669 Notes: 2670 The vectors x and y cannot be the same. I.e., one cannot 2671 call MatMult(A,y,y). 2672 2673 Level: beginner 2674 2675 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2676 @*/ 2677 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2678 { 2679 PetscErrorCode ierr; 2680 2681 PetscFunctionBegin; 2682 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2683 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2684 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2685 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2686 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2687 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2688 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); 2689 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); 2690 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); 2691 2692 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2693 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2694 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2695 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2696 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2697 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2698 PetscFunctionReturn(0); 2699 } 2700 2701 /*@ 2702 MatMultTransposeConstrained - The inner multiplication routine for a 2703 constrained matrix P^T A^T P. 2704 2705 Neighbor-wise Collective on Mat 2706 2707 Input Parameters: 2708 + mat - the matrix 2709 - x - the vector to be multilplied 2710 2711 Output Parameters: 2712 . y - the result 2713 2714 Notes: 2715 The vectors x and y cannot be the same. I.e., one cannot 2716 call MatMult(A,y,y). 2717 2718 Level: beginner 2719 2720 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2721 @*/ 2722 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2723 { 2724 PetscErrorCode ierr; 2725 2726 PetscFunctionBegin; 2727 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2728 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2729 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2730 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2731 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2732 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2733 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); 2734 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); 2735 2736 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2737 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2738 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2739 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2740 PetscFunctionReturn(0); 2741 } 2742 2743 /*@C 2744 MatGetFactorType - gets the type of factorization it is 2745 2746 Not Collective 2747 2748 Input Parameters: 2749 . mat - the matrix 2750 2751 Output Parameters: 2752 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2753 2754 Level: intermediate 2755 2756 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2757 @*/ 2758 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2759 { 2760 PetscFunctionBegin; 2761 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2762 PetscValidType(mat,1); 2763 PetscValidPointer(t,2); 2764 *t = mat->factortype; 2765 PetscFunctionReturn(0); 2766 } 2767 2768 /*@C 2769 MatSetFactorType - sets the type of factorization it is 2770 2771 Logically Collective on Mat 2772 2773 Input Parameters: 2774 + mat - the matrix 2775 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2776 2777 Level: intermediate 2778 2779 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2780 @*/ 2781 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2782 { 2783 PetscFunctionBegin; 2784 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2785 PetscValidType(mat,1); 2786 mat->factortype = t; 2787 PetscFunctionReturn(0); 2788 } 2789 2790 /* ------------------------------------------------------------*/ 2791 /*@C 2792 MatGetInfo - Returns information about matrix storage (number of 2793 nonzeros, memory, etc.). 2794 2795 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2796 2797 Input Parameters: 2798 . mat - the matrix 2799 2800 Output Parameters: 2801 + flag - flag indicating the type of parameters to be returned 2802 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2803 MAT_GLOBAL_SUM - sum over all processors) 2804 - info - matrix information context 2805 2806 Notes: 2807 The MatInfo context contains a variety of matrix data, including 2808 number of nonzeros allocated and used, number of mallocs during 2809 matrix assembly, etc. Additional information for factored matrices 2810 is provided (such as the fill ratio, number of mallocs during 2811 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2812 when using the runtime options 2813 $ -info -mat_view ::ascii_info 2814 2815 Example for C/C++ Users: 2816 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2817 data within the MatInfo context. For example, 2818 .vb 2819 MatInfo info; 2820 Mat A; 2821 double mal, nz_a, nz_u; 2822 2823 MatGetInfo(A,MAT_LOCAL,&info); 2824 mal = info.mallocs; 2825 nz_a = info.nz_allocated; 2826 .ve 2827 2828 Example for Fortran Users: 2829 Fortran users should declare info as a double precision 2830 array of dimension MAT_INFO_SIZE, and then extract the parameters 2831 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2832 a complete list of parameter names. 2833 .vb 2834 double precision info(MAT_INFO_SIZE) 2835 double precision mal, nz_a 2836 Mat A 2837 integer ierr 2838 2839 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2840 mal = info(MAT_INFO_MALLOCS) 2841 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2842 .ve 2843 2844 Level: intermediate 2845 2846 Developer Note: fortran interface is not autogenerated as the f90 2847 interface defintion cannot be generated correctly [due to MatInfo] 2848 2849 .seealso: MatStashGetInfo() 2850 2851 @*/ 2852 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2853 { 2854 PetscErrorCode ierr; 2855 2856 PetscFunctionBegin; 2857 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2858 PetscValidType(mat,1); 2859 PetscValidPointer(info,3); 2860 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2861 MatCheckPreallocated(mat,1); 2862 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2863 PetscFunctionReturn(0); 2864 } 2865 2866 /* 2867 This is used by external packages where it is not easy to get the info from the actual 2868 matrix factorization. 2869 */ 2870 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2871 { 2872 PetscErrorCode ierr; 2873 2874 PetscFunctionBegin; 2875 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2876 PetscFunctionReturn(0); 2877 } 2878 2879 /* ----------------------------------------------------------*/ 2880 2881 /*@C 2882 MatLUFactor - Performs in-place LU factorization of matrix. 2883 2884 Collective on Mat 2885 2886 Input Parameters: 2887 + mat - the matrix 2888 . row - row permutation 2889 . col - column permutation 2890 - info - options for factorization, includes 2891 $ fill - expected fill as ratio of original fill. 2892 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2893 $ Run with the option -info to determine an optimal value to use 2894 2895 Notes: 2896 Most users should employ the simplified KSP interface for linear solvers 2897 instead of working directly with matrix algebra routines such as this. 2898 See, e.g., KSPCreate(). 2899 2900 This changes the state of the matrix to a factored matrix; it cannot be used 2901 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2902 2903 Level: developer 2904 2905 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2906 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2907 2908 Developer Note: fortran interface is not autogenerated as the f90 2909 interface defintion cannot be generated correctly [due to MatFactorInfo] 2910 2911 @*/ 2912 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2913 { 2914 PetscErrorCode ierr; 2915 MatFactorInfo tinfo; 2916 2917 PetscFunctionBegin; 2918 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2919 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2920 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2921 if (info) PetscValidPointer(info,4); 2922 PetscValidType(mat,1); 2923 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2924 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2925 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2926 MatCheckPreallocated(mat,1); 2927 if (!info) { 2928 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2929 info = &tinfo; 2930 } 2931 2932 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2933 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2934 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2935 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2936 PetscFunctionReturn(0); 2937 } 2938 2939 /*@C 2940 MatILUFactor - Performs in-place ILU factorization of matrix. 2941 2942 Collective on Mat 2943 2944 Input Parameters: 2945 + mat - the matrix 2946 . row - row permutation 2947 . col - column permutation 2948 - info - structure containing 2949 $ levels - number of levels of fill. 2950 $ expected fill - as ratio of original fill. 2951 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2952 missing diagonal entries) 2953 2954 Notes: 2955 Probably really in-place only when level of fill is zero, otherwise allocates 2956 new space to store factored matrix and deletes previous memory. 2957 2958 Most users should employ the simplified KSP interface for linear solvers 2959 instead of working directly with matrix algebra routines such as this. 2960 See, e.g., KSPCreate(). 2961 2962 Level: developer 2963 2964 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2965 2966 Developer Note: fortran interface is not autogenerated as the f90 2967 interface defintion cannot be generated correctly [due to MatFactorInfo] 2968 2969 @*/ 2970 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2971 { 2972 PetscErrorCode ierr; 2973 2974 PetscFunctionBegin; 2975 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2976 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2977 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2978 PetscValidPointer(info,4); 2979 PetscValidType(mat,1); 2980 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2981 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2982 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2983 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2984 MatCheckPreallocated(mat,1); 2985 2986 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2987 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2988 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2989 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2990 PetscFunctionReturn(0); 2991 } 2992 2993 /*@C 2994 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2995 Call this routine before calling MatLUFactorNumeric(). 2996 2997 Collective on Mat 2998 2999 Input Parameters: 3000 + fact - the factor matrix obtained with MatGetFactor() 3001 . mat - the matrix 3002 . row, col - row and column permutations 3003 - info - options for factorization, includes 3004 $ fill - expected fill as ratio of original fill. 3005 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3006 $ Run with the option -info to determine an optimal value to use 3007 3008 3009 Notes: 3010 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3011 3012 Most users should employ the simplified KSP interface for linear solvers 3013 instead of working directly with matrix algebra routines such as this. 3014 See, e.g., KSPCreate(). 3015 3016 Level: developer 3017 3018 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 3019 3020 Developer Note: fortran interface is not autogenerated as the f90 3021 interface defintion cannot be generated correctly [due to MatFactorInfo] 3022 3023 @*/ 3024 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3025 { 3026 PetscErrorCode ierr; 3027 3028 PetscFunctionBegin; 3029 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3030 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3031 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3032 if (info) PetscValidPointer(info,4); 3033 PetscValidType(mat,1); 3034 PetscValidPointer(fact,5); 3035 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3036 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3037 if (!(fact)->ops->lufactorsymbolic) { 3038 MatSolverType spackage; 3039 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3040 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3041 } 3042 MatCheckPreallocated(mat,2); 3043 3044 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3045 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3046 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3047 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3048 PetscFunctionReturn(0); 3049 } 3050 3051 /*@C 3052 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3053 Call this routine after first calling MatLUFactorSymbolic(). 3054 3055 Collective on Mat 3056 3057 Input Parameters: 3058 + fact - the factor matrix obtained with MatGetFactor() 3059 . mat - the matrix 3060 - info - options for factorization 3061 3062 Notes: 3063 See MatLUFactor() for in-place factorization. See 3064 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3065 3066 Most users should employ the simplified KSP interface for linear solvers 3067 instead of working directly with matrix algebra routines such as this. 3068 See, e.g., KSPCreate(). 3069 3070 Level: developer 3071 3072 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3073 3074 Developer Note: fortran interface is not autogenerated as the f90 3075 interface defintion cannot be generated correctly [due to MatFactorInfo] 3076 3077 @*/ 3078 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3079 { 3080 PetscErrorCode ierr; 3081 3082 PetscFunctionBegin; 3083 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3084 PetscValidType(mat,1); 3085 PetscValidPointer(fact,2); 3086 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3087 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3088 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); 3089 3090 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3091 MatCheckPreallocated(mat,2); 3092 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3093 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3094 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3095 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3096 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3097 PetscFunctionReturn(0); 3098 } 3099 3100 /*@C 3101 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3102 symmetric matrix. 3103 3104 Collective on Mat 3105 3106 Input Parameters: 3107 + mat - the matrix 3108 . perm - row and column permutations 3109 - f - expected fill as ratio of original fill 3110 3111 Notes: 3112 See MatLUFactor() for the nonsymmetric case. See also 3113 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3114 3115 Most users should employ the simplified KSP interface for linear solvers 3116 instead of working directly with matrix algebra routines such as this. 3117 See, e.g., KSPCreate(). 3118 3119 Level: developer 3120 3121 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3122 MatGetOrdering() 3123 3124 Developer Note: fortran interface is not autogenerated as the f90 3125 interface defintion cannot be generated correctly [due to MatFactorInfo] 3126 3127 @*/ 3128 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3129 { 3130 PetscErrorCode ierr; 3131 3132 PetscFunctionBegin; 3133 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3134 PetscValidType(mat,1); 3135 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3136 if (info) PetscValidPointer(info,3); 3137 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3138 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3139 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3140 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); 3141 MatCheckPreallocated(mat,1); 3142 3143 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3144 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3145 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3146 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3147 PetscFunctionReturn(0); 3148 } 3149 3150 /*@C 3151 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3152 of a symmetric matrix. 3153 3154 Collective on Mat 3155 3156 Input Parameters: 3157 + fact - the factor matrix obtained with MatGetFactor() 3158 . mat - the matrix 3159 . perm - row and column permutations 3160 - info - options for factorization, includes 3161 $ fill - expected fill as ratio of original fill. 3162 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3163 $ Run with the option -info to determine an optimal value to use 3164 3165 Notes: 3166 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3167 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3168 3169 Most users should employ the simplified KSP interface for linear solvers 3170 instead of working directly with matrix algebra routines such as this. 3171 See, e.g., KSPCreate(). 3172 3173 Level: developer 3174 3175 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3176 MatGetOrdering() 3177 3178 Developer Note: fortran interface is not autogenerated as the f90 3179 interface defintion cannot be generated correctly [due to MatFactorInfo] 3180 3181 @*/ 3182 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3183 { 3184 PetscErrorCode ierr; 3185 3186 PetscFunctionBegin; 3187 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3188 PetscValidType(mat,1); 3189 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3190 if (info) PetscValidPointer(info,3); 3191 PetscValidPointer(fact,4); 3192 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3193 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3194 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3195 if (!(fact)->ops->choleskyfactorsymbolic) { 3196 MatSolverType spackage; 3197 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3198 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3199 } 3200 MatCheckPreallocated(mat,2); 3201 3202 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3203 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3204 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3205 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3206 PetscFunctionReturn(0); 3207 } 3208 3209 /*@C 3210 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3211 of a symmetric matrix. Call this routine after first calling 3212 MatCholeskyFactorSymbolic(). 3213 3214 Collective on Mat 3215 3216 Input Parameters: 3217 + fact - the factor matrix obtained with MatGetFactor() 3218 . mat - the initial matrix 3219 . info - options for factorization 3220 - fact - the symbolic factor of mat 3221 3222 3223 Notes: 3224 Most users should employ the simplified KSP interface for linear solvers 3225 instead of working directly with matrix algebra routines such as this. 3226 See, e.g., KSPCreate(). 3227 3228 Level: developer 3229 3230 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3231 3232 Developer Note: fortran interface is not autogenerated as the f90 3233 interface defintion cannot be generated correctly [due to MatFactorInfo] 3234 3235 @*/ 3236 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3237 { 3238 PetscErrorCode ierr; 3239 3240 PetscFunctionBegin; 3241 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3242 PetscValidType(mat,1); 3243 PetscValidPointer(fact,2); 3244 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3245 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3246 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3247 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); 3248 MatCheckPreallocated(mat,2); 3249 3250 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3251 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3252 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3253 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3254 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3255 PetscFunctionReturn(0); 3256 } 3257 3258 /* ----------------------------------------------------------------*/ 3259 /*@ 3260 MatSolve - Solves A x = b, given a factored matrix. 3261 3262 Neighbor-wise Collective on Mat 3263 3264 Input Parameters: 3265 + mat - the factored matrix 3266 - b - the right-hand-side vector 3267 3268 Output Parameter: 3269 . x - the result vector 3270 3271 Notes: 3272 The vectors b and x cannot be the same. I.e., one cannot 3273 call MatSolve(A,x,x). 3274 3275 Notes: 3276 Most users should employ the simplified KSP interface for linear solvers 3277 instead of working directly with matrix algebra routines such as this. 3278 See, e.g., KSPCreate(). 3279 3280 Level: developer 3281 3282 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3283 @*/ 3284 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3285 { 3286 PetscErrorCode ierr; 3287 3288 PetscFunctionBegin; 3289 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3290 PetscValidType(mat,1); 3291 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3292 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3293 PetscCheckSameComm(mat,1,b,2); 3294 PetscCheckSameComm(mat,1,x,3); 3295 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3296 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); 3297 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); 3298 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); 3299 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3300 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3301 MatCheckPreallocated(mat,1); 3302 3303 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3304 if (mat->factorerrortype) { 3305 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3306 ierr = VecSetInf(x);CHKERRQ(ierr); 3307 } else { 3308 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3309 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3310 } 3311 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3312 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3313 PetscFunctionReturn(0); 3314 } 3315 3316 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans) 3317 { 3318 PetscErrorCode ierr; 3319 Vec b,x; 3320 PetscInt m,N,i; 3321 PetscScalar *bb,*xx; 3322 3323 PetscFunctionBegin; 3324 ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr); 3325 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3326 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3327 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3328 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3329 for (i=0; i<N; i++) { 3330 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3331 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3332 if (trans) { 3333 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3334 } else { 3335 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3336 } 3337 ierr = VecResetArray(x);CHKERRQ(ierr); 3338 ierr = VecResetArray(b);CHKERRQ(ierr); 3339 } 3340 ierr = VecDestroy(&b);CHKERRQ(ierr); 3341 ierr = VecDestroy(&x);CHKERRQ(ierr); 3342 ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr); 3343 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3344 PetscFunctionReturn(0); 3345 } 3346 3347 /*@ 3348 MatMatSolve - Solves A X = B, given a factored matrix. 3349 3350 Neighbor-wise Collective on Mat 3351 3352 Input Parameters: 3353 + A - the factored matrix 3354 - B - the right-hand-side matrix (dense matrix) 3355 3356 Output Parameter: 3357 . X - the result matrix (dense matrix) 3358 3359 Notes: 3360 The matrices b and x cannot be the same. I.e., one cannot 3361 call MatMatSolve(A,x,x). 3362 3363 Notes: 3364 Most users should usually employ the simplified KSP interface for linear solvers 3365 instead of working directly with matrix algebra routines such as this. 3366 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3367 at a time. 3368 3369 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3370 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3371 3372 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3373 3374 Level: developer 3375 3376 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3377 @*/ 3378 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3379 { 3380 PetscErrorCode ierr; 3381 3382 PetscFunctionBegin; 3383 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3384 PetscValidType(A,1); 3385 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3386 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3387 PetscCheckSameComm(A,1,B,2); 3388 PetscCheckSameComm(A,1,X,3); 3389 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3390 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); 3391 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); 3392 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"); 3393 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3394 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3395 MatCheckPreallocated(A,1); 3396 3397 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3398 if (!A->ops->matsolve) { 3399 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3400 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3401 } else { 3402 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3403 } 3404 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3405 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3406 PetscFunctionReturn(0); 3407 } 3408 3409 /*@ 3410 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3411 3412 Neighbor-wise Collective on Mat 3413 3414 Input Parameters: 3415 + A - the factored matrix 3416 - B - the right-hand-side matrix (dense matrix) 3417 3418 Output Parameter: 3419 . X - the result matrix (dense matrix) 3420 3421 Notes: 3422 The matrices B and X cannot be the same. I.e., one cannot 3423 call MatMatSolveTranspose(A,X,X). 3424 3425 Notes: 3426 Most users should usually employ the simplified KSP interface for linear solvers 3427 instead of working directly with matrix algebra routines such as this. 3428 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3429 at a time. 3430 3431 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3432 3433 Level: developer 3434 3435 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3436 @*/ 3437 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3438 { 3439 PetscErrorCode ierr; 3440 3441 PetscFunctionBegin; 3442 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3443 PetscValidType(A,1); 3444 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3445 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3446 PetscCheckSameComm(A,1,B,2); 3447 PetscCheckSameComm(A,1,X,3); 3448 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3449 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); 3450 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); 3451 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); 3452 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"); 3453 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3454 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3455 MatCheckPreallocated(A,1); 3456 3457 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3458 if (!A->ops->matsolvetranspose) { 3459 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3460 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3461 } else { 3462 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3463 } 3464 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3465 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3466 PetscFunctionReturn(0); 3467 } 3468 3469 /*@ 3470 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3471 3472 Neighbor-wise Collective on Mat 3473 3474 Input Parameters: 3475 + A - the factored matrix 3476 - Bt - the transpose of right-hand-side matrix 3477 3478 Output Parameter: 3479 . X - the result matrix (dense matrix) 3480 3481 Notes: 3482 Most users should usually employ the simplified KSP interface for linear solvers 3483 instead of working directly with matrix algebra routines such as this. 3484 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3485 at a time. 3486 3487 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(). 3488 3489 Level: developer 3490 3491 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3492 @*/ 3493 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3494 { 3495 PetscErrorCode ierr; 3496 3497 PetscFunctionBegin; 3498 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3499 PetscValidType(A,1); 3500 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3501 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3502 PetscCheckSameComm(A,1,Bt,2); 3503 PetscCheckSameComm(A,1,X,3); 3504 3505 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3506 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); 3507 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); 3508 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"); 3509 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3510 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3511 MatCheckPreallocated(A,1); 3512 3513 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3514 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3515 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3516 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3517 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3518 PetscFunctionReturn(0); 3519 } 3520 3521 /*@ 3522 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3523 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3524 3525 Neighbor-wise Collective on Mat 3526 3527 Input Parameters: 3528 + mat - the factored matrix 3529 - b - the right-hand-side vector 3530 3531 Output Parameter: 3532 . x - the result vector 3533 3534 Notes: 3535 MatSolve() should be used for most applications, as it performs 3536 a forward solve followed by a backward solve. 3537 3538 The vectors b and x cannot be the same, i.e., one cannot 3539 call MatForwardSolve(A,x,x). 3540 3541 For matrix in seqsbaij format with block size larger than 1, 3542 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3543 MatForwardSolve() solves U^T*D y = b, and 3544 MatBackwardSolve() solves U x = y. 3545 Thus they do not provide a symmetric preconditioner. 3546 3547 Most users should employ the simplified KSP interface for linear solvers 3548 instead of working directly with matrix algebra routines such as this. 3549 See, e.g., KSPCreate(). 3550 3551 Level: developer 3552 3553 .seealso: MatSolve(), MatBackwardSolve() 3554 @*/ 3555 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3556 { 3557 PetscErrorCode ierr; 3558 3559 PetscFunctionBegin; 3560 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3561 PetscValidType(mat,1); 3562 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3563 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3564 PetscCheckSameComm(mat,1,b,2); 3565 PetscCheckSameComm(mat,1,x,3); 3566 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3567 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); 3568 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); 3569 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); 3570 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3571 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3572 MatCheckPreallocated(mat,1); 3573 3574 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3575 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3576 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3577 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3578 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3579 PetscFunctionReturn(0); 3580 } 3581 3582 /*@ 3583 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3584 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3585 3586 Neighbor-wise Collective on Mat 3587 3588 Input Parameters: 3589 + mat - the factored matrix 3590 - b - the right-hand-side vector 3591 3592 Output Parameter: 3593 . x - the result vector 3594 3595 Notes: 3596 MatSolve() should be used for most applications, as it performs 3597 a forward solve followed by a backward solve. 3598 3599 The vectors b and x cannot be the same. I.e., one cannot 3600 call MatBackwardSolve(A,x,x). 3601 3602 For matrix in seqsbaij format with block size larger than 1, 3603 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3604 MatForwardSolve() solves U^T*D y = b, and 3605 MatBackwardSolve() solves U x = y. 3606 Thus they do not provide a symmetric preconditioner. 3607 3608 Most users should employ the simplified KSP interface for linear solvers 3609 instead of working directly with matrix algebra routines such as this. 3610 See, e.g., KSPCreate(). 3611 3612 Level: developer 3613 3614 .seealso: MatSolve(), MatForwardSolve() 3615 @*/ 3616 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3617 { 3618 PetscErrorCode ierr; 3619 3620 PetscFunctionBegin; 3621 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3622 PetscValidType(mat,1); 3623 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3624 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3625 PetscCheckSameComm(mat,1,b,2); 3626 PetscCheckSameComm(mat,1,x,3); 3627 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3628 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); 3629 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); 3630 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); 3631 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3632 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3633 MatCheckPreallocated(mat,1); 3634 3635 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3636 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3637 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3638 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3639 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3640 PetscFunctionReturn(0); 3641 } 3642 3643 /*@ 3644 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3645 3646 Neighbor-wise Collective on Mat 3647 3648 Input Parameters: 3649 + mat - the factored matrix 3650 . b - the right-hand-side vector 3651 - y - the vector to be added to 3652 3653 Output Parameter: 3654 . x - the result vector 3655 3656 Notes: 3657 The vectors b and x cannot be the same. I.e., one cannot 3658 call MatSolveAdd(A,x,y,x). 3659 3660 Most users should employ the simplified KSP interface for linear solvers 3661 instead of working directly with matrix algebra routines such as this. 3662 See, e.g., KSPCreate(). 3663 3664 Level: developer 3665 3666 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3667 @*/ 3668 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3669 { 3670 PetscScalar one = 1.0; 3671 Vec tmp; 3672 PetscErrorCode ierr; 3673 3674 PetscFunctionBegin; 3675 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3676 PetscValidType(mat,1); 3677 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3678 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3679 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3680 PetscCheckSameComm(mat,1,b,2); 3681 PetscCheckSameComm(mat,1,y,2); 3682 PetscCheckSameComm(mat,1,x,3); 3683 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3684 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); 3685 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); 3686 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); 3687 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); 3688 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); 3689 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3690 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3691 MatCheckPreallocated(mat,1); 3692 3693 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3694 if (mat->ops->solveadd) { 3695 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3696 } else { 3697 /* do the solve then the add manually */ 3698 if (x != y) { 3699 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3700 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3701 } else { 3702 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3703 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3704 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3705 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3706 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3707 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3708 } 3709 } 3710 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3711 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3712 PetscFunctionReturn(0); 3713 } 3714 3715 /*@ 3716 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3717 3718 Neighbor-wise Collective on Mat 3719 3720 Input Parameters: 3721 + mat - the factored matrix 3722 - b - the right-hand-side vector 3723 3724 Output Parameter: 3725 . x - the result vector 3726 3727 Notes: 3728 The vectors b and x cannot be the same. I.e., one cannot 3729 call MatSolveTranspose(A,x,x). 3730 3731 Most users should employ the simplified KSP interface for linear solvers 3732 instead of working directly with matrix algebra routines such as this. 3733 See, e.g., KSPCreate(). 3734 3735 Level: developer 3736 3737 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3738 @*/ 3739 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3740 { 3741 PetscErrorCode ierr; 3742 3743 PetscFunctionBegin; 3744 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3745 PetscValidType(mat,1); 3746 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3747 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3748 PetscCheckSameComm(mat,1,b,2); 3749 PetscCheckSameComm(mat,1,x,3); 3750 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3751 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); 3752 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); 3753 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3754 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3755 MatCheckPreallocated(mat,1); 3756 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3757 if (mat->factorerrortype) { 3758 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3759 ierr = VecSetInf(x);CHKERRQ(ierr); 3760 } else { 3761 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3762 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3763 } 3764 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3765 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3766 PetscFunctionReturn(0); 3767 } 3768 3769 /*@ 3770 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3771 factored matrix. 3772 3773 Neighbor-wise Collective on Mat 3774 3775 Input Parameters: 3776 + mat - the factored matrix 3777 . b - the right-hand-side vector 3778 - y - the vector to be added to 3779 3780 Output Parameter: 3781 . x - the result vector 3782 3783 Notes: 3784 The vectors b and x cannot be the same. I.e., one cannot 3785 call MatSolveTransposeAdd(A,x,y,x). 3786 3787 Most users should employ the simplified KSP interface for linear solvers 3788 instead of working directly with matrix algebra routines such as this. 3789 See, e.g., KSPCreate(). 3790 3791 Level: developer 3792 3793 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3794 @*/ 3795 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3796 { 3797 PetscScalar one = 1.0; 3798 PetscErrorCode ierr; 3799 Vec tmp; 3800 3801 PetscFunctionBegin; 3802 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3803 PetscValidType(mat,1); 3804 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3805 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3806 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3807 PetscCheckSameComm(mat,1,b,2); 3808 PetscCheckSameComm(mat,1,y,3); 3809 PetscCheckSameComm(mat,1,x,4); 3810 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3811 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); 3812 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); 3813 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); 3814 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); 3815 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3816 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3817 MatCheckPreallocated(mat,1); 3818 3819 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3820 if (mat->ops->solvetransposeadd) { 3821 if (mat->factorerrortype) { 3822 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3823 ierr = VecSetInf(x);CHKERRQ(ierr); 3824 } else { 3825 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3826 } 3827 } else { 3828 /* do the solve then the add manually */ 3829 if (x != y) { 3830 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3831 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3832 } else { 3833 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3834 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3835 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3836 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3837 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3838 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3839 } 3840 } 3841 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3842 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3843 PetscFunctionReturn(0); 3844 } 3845 /* ----------------------------------------------------------------*/ 3846 3847 /*@ 3848 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3849 3850 Neighbor-wise Collective on Mat 3851 3852 Input Parameters: 3853 + mat - the matrix 3854 . b - the right hand side 3855 . omega - the relaxation factor 3856 . flag - flag indicating the type of SOR (see below) 3857 . shift - diagonal shift 3858 . its - the number of iterations 3859 - lits - the number of local iterations 3860 3861 Output Parameters: 3862 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3863 3864 SOR Flags: 3865 + SOR_FORWARD_SWEEP - forward SOR 3866 . SOR_BACKWARD_SWEEP - backward SOR 3867 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3868 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3869 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3870 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3871 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3872 upper/lower triangular part of matrix to 3873 vector (with omega) 3874 - SOR_ZERO_INITIAL_GUESS - zero initial guess 3875 3876 Notes: 3877 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3878 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3879 on each processor. 3880 3881 Application programmers will not generally use MatSOR() directly, 3882 but instead will employ the KSP/PC interface. 3883 3884 Notes: 3885 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3886 3887 Notes for Advanced Users: 3888 The flags are implemented as bitwise inclusive or operations. 3889 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3890 to specify a zero initial guess for SSOR. 3891 3892 Most users should employ the simplified KSP interface for linear solvers 3893 instead of working directly with matrix algebra routines such as this. 3894 See, e.g., KSPCreate(). 3895 3896 Vectors x and b CANNOT be the same 3897 3898 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3899 3900 Level: developer 3901 3902 @*/ 3903 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3904 { 3905 PetscErrorCode ierr; 3906 3907 PetscFunctionBegin; 3908 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3909 PetscValidType(mat,1); 3910 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3911 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3912 PetscCheckSameComm(mat,1,b,2); 3913 PetscCheckSameComm(mat,1,x,8); 3914 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3915 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3916 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3917 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); 3918 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); 3919 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); 3920 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3921 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3922 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3923 3924 MatCheckPreallocated(mat,1); 3925 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3926 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3927 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3928 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3929 PetscFunctionReturn(0); 3930 } 3931 3932 /* 3933 Default matrix copy routine. 3934 */ 3935 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3936 { 3937 PetscErrorCode ierr; 3938 PetscInt i,rstart = 0,rend = 0,nz; 3939 const PetscInt *cwork; 3940 const PetscScalar *vwork; 3941 3942 PetscFunctionBegin; 3943 if (B->assembled) { 3944 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3945 } 3946 if (str == SAME_NONZERO_PATTERN) { 3947 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3948 for (i=rstart; i<rend; i++) { 3949 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3950 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3951 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3952 } 3953 } else { 3954 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr); 3955 } 3956 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3957 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3958 PetscFunctionReturn(0); 3959 } 3960 3961 /*@ 3962 MatCopy - Copies a matrix to another matrix. 3963 3964 Collective on Mat 3965 3966 Input Parameters: 3967 + A - the matrix 3968 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3969 3970 Output Parameter: 3971 . B - where the copy is put 3972 3973 Notes: 3974 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3975 same nonzero pattern or the routine will crash. 3976 3977 MatCopy() copies the matrix entries of a matrix to another existing 3978 matrix (after first zeroing the second matrix). A related routine is 3979 MatConvert(), which first creates a new matrix and then copies the data. 3980 3981 Level: intermediate 3982 3983 .seealso: MatConvert(), MatDuplicate() 3984 3985 @*/ 3986 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3987 { 3988 PetscErrorCode ierr; 3989 PetscInt i; 3990 3991 PetscFunctionBegin; 3992 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3993 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3994 PetscValidType(A,1); 3995 PetscValidType(B,2); 3996 PetscCheckSameComm(A,1,B,2); 3997 MatCheckPreallocated(B,2); 3998 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3999 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4000 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); 4001 MatCheckPreallocated(A,1); 4002 if (A == B) PetscFunctionReturn(0); 4003 4004 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4005 if (A->ops->copy) { 4006 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4007 } else { /* generic conversion */ 4008 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4009 } 4010 4011 B->stencil.dim = A->stencil.dim; 4012 B->stencil.noc = A->stencil.noc; 4013 for (i=0; i<=A->stencil.dim; i++) { 4014 B->stencil.dims[i] = A->stencil.dims[i]; 4015 B->stencil.starts[i] = A->stencil.starts[i]; 4016 } 4017 4018 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4019 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4020 PetscFunctionReturn(0); 4021 } 4022 4023 /*@C 4024 MatConvert - Converts a matrix to another matrix, either of the same 4025 or different type. 4026 4027 Collective on Mat 4028 4029 Input Parameters: 4030 + mat - the matrix 4031 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4032 same type as the original matrix. 4033 - reuse - denotes if the destination matrix is to be created or reused. 4034 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 4035 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). 4036 4037 Output Parameter: 4038 . M - pointer to place new matrix 4039 4040 Notes: 4041 MatConvert() first creates a new matrix and then copies the data from 4042 the first matrix. A related routine is MatCopy(), which copies the matrix 4043 entries of one matrix to another already existing matrix context. 4044 4045 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4046 the MPI communicator of the generated matrix is always the same as the communicator 4047 of the input matrix. 4048 4049 Level: intermediate 4050 4051 .seealso: MatCopy(), MatDuplicate() 4052 @*/ 4053 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4054 { 4055 PetscErrorCode ierr; 4056 PetscBool sametype,issame,flg; 4057 char convname[256],mtype[256]; 4058 Mat B; 4059 4060 PetscFunctionBegin; 4061 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4062 PetscValidType(mat,1); 4063 PetscValidPointer(M,3); 4064 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4065 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4066 MatCheckPreallocated(mat,1); 4067 4068 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4069 if (flg) { 4070 newtype = mtype; 4071 } 4072 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4073 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4074 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4075 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"); 4076 4077 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 4078 4079 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4080 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4081 } else { 4082 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4083 const char *prefix[3] = {"seq","mpi",""}; 4084 PetscInt i; 4085 /* 4086 Order of precedence: 4087 0) See if newtype is a superclass of the current matrix. 4088 1) See if a specialized converter is known to the current matrix. 4089 2) See if a specialized converter is known to the desired matrix class. 4090 3) See if a good general converter is registered for the desired class 4091 (as of 6/27/03 only MATMPIADJ falls into this category). 4092 4) See if a good general converter is known for the current matrix. 4093 5) Use a really basic converter. 4094 */ 4095 4096 /* 0) See if newtype is a superclass of the current matrix. 4097 i.e mat is mpiaij and newtype is aij */ 4098 for (i=0; i<2; i++) { 4099 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4100 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4101 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4102 ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr); 4103 if (flg) { 4104 if (reuse == MAT_INPLACE_MATRIX) { 4105 PetscFunctionReturn(0); 4106 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4107 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4108 PetscFunctionReturn(0); 4109 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4110 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4111 PetscFunctionReturn(0); 4112 } 4113 } 4114 } 4115 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4116 for (i=0; i<3; i++) { 4117 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4118 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4119 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4120 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4121 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4122 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4123 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4124 ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4125 if (conv) goto foundconv; 4126 } 4127 4128 /* 2) See if a specialized converter is known to the desired matrix class. */ 4129 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4130 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4131 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4132 for (i=0; i<3; i++) { 4133 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4134 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4135 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4136 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4137 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4138 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4139 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4140 ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4141 if (conv) { 4142 ierr = MatDestroy(&B);CHKERRQ(ierr); 4143 goto foundconv; 4144 } 4145 } 4146 4147 /* 3) See if a good general converter is registered for the desired class */ 4148 conv = B->ops->convertfrom; 4149 ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4150 ierr = MatDestroy(&B);CHKERRQ(ierr); 4151 if (conv) goto foundconv; 4152 4153 /* 4) See if a good general converter is known for the current matrix */ 4154 if (mat->ops->convert) { 4155 conv = mat->ops->convert; 4156 } 4157 ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4158 if (conv) goto foundconv; 4159 4160 /* 5) Use a really basic converter. */ 4161 ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr); 4162 conv = MatConvert_Basic; 4163 4164 foundconv: 4165 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4166 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4167 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4168 /* the block sizes must be same if the mappings are copied over */ 4169 (*M)->rmap->bs = mat->rmap->bs; 4170 (*M)->cmap->bs = mat->cmap->bs; 4171 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4172 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4173 (*M)->rmap->mapping = mat->rmap->mapping; 4174 (*M)->cmap->mapping = mat->cmap->mapping; 4175 } 4176 (*M)->stencil.dim = mat->stencil.dim; 4177 (*M)->stencil.noc = mat->stencil.noc; 4178 for (i=0; i<=mat->stencil.dim; i++) { 4179 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4180 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4181 } 4182 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4183 } 4184 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4185 4186 /* Copy Mat options */ 4187 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4188 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4189 PetscFunctionReturn(0); 4190 } 4191 4192 /*@C 4193 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4194 4195 Not Collective 4196 4197 Input Parameter: 4198 . mat - the matrix, must be a factored matrix 4199 4200 Output Parameter: 4201 . type - the string name of the package (do not free this string) 4202 4203 Notes: 4204 In Fortran you pass in a empty string and the package name will be copied into it. 4205 (Make sure the string is long enough) 4206 4207 Level: intermediate 4208 4209 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4210 @*/ 4211 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4212 { 4213 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4214 4215 PetscFunctionBegin; 4216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4217 PetscValidType(mat,1); 4218 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4219 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4220 if (!conv) { 4221 *type = MATSOLVERPETSC; 4222 } else { 4223 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4224 } 4225 PetscFunctionReturn(0); 4226 } 4227 4228 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4229 struct _MatSolverTypeForSpecifcType { 4230 MatType mtype; 4231 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4232 MatSolverTypeForSpecifcType next; 4233 }; 4234 4235 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4236 struct _MatSolverTypeHolder { 4237 char *name; 4238 MatSolverTypeForSpecifcType handlers; 4239 MatSolverTypeHolder next; 4240 }; 4241 4242 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4243 4244 /*@C 4245 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4246 4247 Input Parameters: 4248 + package - name of the package, for example petsc or superlu 4249 . mtype - the matrix type that works with this package 4250 . ftype - the type of factorization supported by the package 4251 - getfactor - routine that will create the factored matrix ready to be used 4252 4253 Level: intermediate 4254 4255 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4256 @*/ 4257 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4258 { 4259 PetscErrorCode ierr; 4260 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4261 PetscBool flg; 4262 MatSolverTypeForSpecifcType inext,iprev = NULL; 4263 4264 PetscFunctionBegin; 4265 ierr = MatInitializePackage();CHKERRQ(ierr); 4266 if (!next) { 4267 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4268 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4269 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4270 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4271 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4272 PetscFunctionReturn(0); 4273 } 4274 while (next) { 4275 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4276 if (flg) { 4277 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4278 inext = next->handlers; 4279 while (inext) { 4280 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4281 if (flg) { 4282 inext->getfactor[(int)ftype-1] = getfactor; 4283 PetscFunctionReturn(0); 4284 } 4285 iprev = inext; 4286 inext = inext->next; 4287 } 4288 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4289 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4290 iprev->next->getfactor[(int)ftype-1] = getfactor; 4291 PetscFunctionReturn(0); 4292 } 4293 prev = next; 4294 next = next->next; 4295 } 4296 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4297 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4298 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4299 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4300 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4301 PetscFunctionReturn(0); 4302 } 4303 4304 /*@C 4305 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4306 4307 Input Parameters: 4308 + package - name of the package, for example petsc or superlu 4309 . ftype - the type of factorization supported by the package 4310 - mtype - the matrix type that works with this package 4311 4312 Output Parameters: 4313 + foundpackage - PETSC_TRUE if the package was registered 4314 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4315 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4316 4317 Level: intermediate 4318 4319 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4320 @*/ 4321 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4322 { 4323 PetscErrorCode ierr; 4324 MatSolverTypeHolder next = MatSolverTypeHolders; 4325 PetscBool flg; 4326 MatSolverTypeForSpecifcType inext; 4327 4328 PetscFunctionBegin; 4329 if (foundpackage) *foundpackage = PETSC_FALSE; 4330 if (foundmtype) *foundmtype = PETSC_FALSE; 4331 if (getfactor) *getfactor = NULL; 4332 4333 if (package) { 4334 while (next) { 4335 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4336 if (flg) { 4337 if (foundpackage) *foundpackage = PETSC_TRUE; 4338 inext = next->handlers; 4339 while (inext) { 4340 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4341 if (flg) { 4342 if (foundmtype) *foundmtype = PETSC_TRUE; 4343 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4344 PetscFunctionReturn(0); 4345 } 4346 inext = inext->next; 4347 } 4348 } 4349 next = next->next; 4350 } 4351 } else { 4352 while (next) { 4353 inext = next->handlers; 4354 while (inext) { 4355 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4356 if (flg && inext->getfactor[(int)ftype-1]) { 4357 if (foundpackage) *foundpackage = PETSC_TRUE; 4358 if (foundmtype) *foundmtype = PETSC_TRUE; 4359 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4360 PetscFunctionReturn(0); 4361 } 4362 inext = inext->next; 4363 } 4364 next = next->next; 4365 } 4366 } 4367 PetscFunctionReturn(0); 4368 } 4369 4370 PetscErrorCode MatSolverTypeDestroy(void) 4371 { 4372 PetscErrorCode ierr; 4373 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4374 MatSolverTypeForSpecifcType inext,iprev; 4375 4376 PetscFunctionBegin; 4377 while (next) { 4378 ierr = PetscFree(next->name);CHKERRQ(ierr); 4379 inext = next->handlers; 4380 while (inext) { 4381 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4382 iprev = inext; 4383 inext = inext->next; 4384 ierr = PetscFree(iprev);CHKERRQ(ierr); 4385 } 4386 prev = next; 4387 next = next->next; 4388 ierr = PetscFree(prev);CHKERRQ(ierr); 4389 } 4390 MatSolverTypeHolders = NULL; 4391 PetscFunctionReturn(0); 4392 } 4393 4394 /*@C 4395 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4396 4397 Collective on Mat 4398 4399 Input Parameters: 4400 + mat - the matrix 4401 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4402 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4403 4404 Output Parameters: 4405 . f - the factor matrix used with MatXXFactorSymbolic() calls 4406 4407 Notes: 4408 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4409 such as pastix, superlu, mumps etc. 4410 4411 PETSc must have been ./configure to use the external solver, using the option --download-package 4412 4413 Level: intermediate 4414 4415 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4416 @*/ 4417 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4418 { 4419 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4420 PetscBool foundpackage,foundmtype; 4421 4422 PetscFunctionBegin; 4423 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4424 PetscValidType(mat,1); 4425 4426 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4427 MatCheckPreallocated(mat,1); 4428 4429 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4430 if (!foundpackage) { 4431 if (type) { 4432 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4433 } else { 4434 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4435 } 4436 } 4437 4438 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4439 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); 4440 4441 #if defined(PETSC_USE_COMPLEX) 4442 if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported"); 4443 #endif 4444 4445 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4446 PetscFunctionReturn(0); 4447 } 4448 4449 /*@C 4450 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4451 4452 Not Collective 4453 4454 Input Parameters: 4455 + mat - the matrix 4456 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4457 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4458 4459 Output Parameter: 4460 . flg - PETSC_TRUE if the factorization is available 4461 4462 Notes: 4463 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4464 such as pastix, superlu, mumps etc. 4465 4466 PETSc must have been ./configure to use the external solver, using the option --download-package 4467 4468 Level: intermediate 4469 4470 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4471 @*/ 4472 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4473 { 4474 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4475 4476 PetscFunctionBegin; 4477 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4478 PetscValidType(mat,1); 4479 4480 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4481 MatCheckPreallocated(mat,1); 4482 4483 *flg = PETSC_FALSE; 4484 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4485 if (gconv) { 4486 *flg = PETSC_TRUE; 4487 } 4488 PetscFunctionReturn(0); 4489 } 4490 4491 #include <petscdmtypes.h> 4492 4493 /*@ 4494 MatDuplicate - Duplicates a matrix including the non-zero structure. 4495 4496 Collective on Mat 4497 4498 Input Parameters: 4499 + mat - the matrix 4500 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4501 See the manual page for MatDuplicateOption for an explanation of these options. 4502 4503 Output Parameter: 4504 . M - pointer to place new matrix 4505 4506 Level: intermediate 4507 4508 Notes: 4509 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4510 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. 4511 4512 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4513 @*/ 4514 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4515 { 4516 PetscErrorCode ierr; 4517 Mat B; 4518 PetscInt i; 4519 DM dm; 4520 void (*viewf)(void); 4521 4522 PetscFunctionBegin; 4523 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4524 PetscValidType(mat,1); 4525 PetscValidPointer(M,3); 4526 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4527 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4528 MatCheckPreallocated(mat,1); 4529 4530 *M = 0; 4531 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4532 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4533 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4534 B = *M; 4535 4536 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4537 if (viewf) { 4538 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4539 } 4540 4541 B->stencil.dim = mat->stencil.dim; 4542 B->stencil.noc = mat->stencil.noc; 4543 for (i=0; i<=mat->stencil.dim; i++) { 4544 B->stencil.dims[i] = mat->stencil.dims[i]; 4545 B->stencil.starts[i] = mat->stencil.starts[i]; 4546 } 4547 4548 B->nooffproczerorows = mat->nooffproczerorows; 4549 B->nooffprocentries = mat->nooffprocentries; 4550 4551 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4552 if (dm) { 4553 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4554 } 4555 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4556 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4557 PetscFunctionReturn(0); 4558 } 4559 4560 /*@ 4561 MatGetDiagonal - Gets the diagonal of a matrix. 4562 4563 Logically Collective on Mat 4564 4565 Input Parameters: 4566 + mat - the matrix 4567 - v - the vector for storing the diagonal 4568 4569 Output Parameter: 4570 . v - the diagonal of the matrix 4571 4572 Level: intermediate 4573 4574 Note: 4575 Currently only correct in parallel for square matrices. 4576 4577 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4578 @*/ 4579 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4580 { 4581 PetscErrorCode ierr; 4582 4583 PetscFunctionBegin; 4584 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4585 PetscValidType(mat,1); 4586 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4587 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4588 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4589 MatCheckPreallocated(mat,1); 4590 4591 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4592 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4593 PetscFunctionReturn(0); 4594 } 4595 4596 /*@C 4597 MatGetRowMin - Gets the minimum value (of the real part) of each 4598 row of the matrix 4599 4600 Logically Collective on Mat 4601 4602 Input Parameters: 4603 . mat - the matrix 4604 4605 Output Parameter: 4606 + v - the vector for storing the maximums 4607 - idx - the indices of the column found for each row (optional) 4608 4609 Level: intermediate 4610 4611 Notes: 4612 The result of this call are the same as if one converted the matrix to dense format 4613 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4614 4615 This code is only implemented for a couple of matrix formats. 4616 4617 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4618 MatGetRowMax() 4619 @*/ 4620 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4621 { 4622 PetscErrorCode ierr; 4623 4624 PetscFunctionBegin; 4625 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4626 PetscValidType(mat,1); 4627 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4628 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4629 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4630 MatCheckPreallocated(mat,1); 4631 4632 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4633 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4634 PetscFunctionReturn(0); 4635 } 4636 4637 /*@C 4638 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4639 row of the matrix 4640 4641 Logically Collective on Mat 4642 4643 Input Parameters: 4644 . mat - the matrix 4645 4646 Output Parameter: 4647 + v - the vector for storing the minimums 4648 - idx - the indices of the column found for each row (or NULL if not needed) 4649 4650 Level: intermediate 4651 4652 Notes: 4653 if a row is completely empty or has only 0.0 values then the idx[] value for that 4654 row is 0 (the first column). 4655 4656 This code is only implemented for a couple of matrix formats. 4657 4658 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4659 @*/ 4660 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4661 { 4662 PetscErrorCode ierr; 4663 4664 PetscFunctionBegin; 4665 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4666 PetscValidType(mat,1); 4667 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4668 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4669 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4670 MatCheckPreallocated(mat,1); 4671 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4672 4673 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4674 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4675 PetscFunctionReturn(0); 4676 } 4677 4678 /*@C 4679 MatGetRowMax - Gets the maximum value (of the real part) of each 4680 row of the matrix 4681 4682 Logically Collective on Mat 4683 4684 Input Parameters: 4685 . mat - the matrix 4686 4687 Output Parameter: 4688 + v - the vector for storing the maximums 4689 - idx - the indices of the column found for each row (optional) 4690 4691 Level: intermediate 4692 4693 Notes: 4694 The result of this call are the same as if one converted the matrix to dense format 4695 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4696 4697 This code is only implemented for a couple of matrix formats. 4698 4699 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4700 @*/ 4701 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4702 { 4703 PetscErrorCode ierr; 4704 4705 PetscFunctionBegin; 4706 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4707 PetscValidType(mat,1); 4708 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4709 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4710 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4711 MatCheckPreallocated(mat,1); 4712 4713 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4714 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4715 PetscFunctionReturn(0); 4716 } 4717 4718 /*@C 4719 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4720 row of the matrix 4721 4722 Logically Collective on Mat 4723 4724 Input Parameters: 4725 . mat - the matrix 4726 4727 Output Parameter: 4728 + v - the vector for storing the maximums 4729 - idx - the indices of the column found for each row (or NULL if not needed) 4730 4731 Level: intermediate 4732 4733 Notes: 4734 if a row is completely empty or has only 0.0 values then the idx[] value for that 4735 row is 0 (the first column). 4736 4737 This code is only implemented for a couple of matrix formats. 4738 4739 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4740 @*/ 4741 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4742 { 4743 PetscErrorCode ierr; 4744 4745 PetscFunctionBegin; 4746 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4747 PetscValidType(mat,1); 4748 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4749 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4750 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4751 MatCheckPreallocated(mat,1); 4752 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4753 4754 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4755 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4756 PetscFunctionReturn(0); 4757 } 4758 4759 /*@ 4760 MatGetRowSum - Gets the sum of each row of the matrix 4761 4762 Logically or Neighborhood Collective on Mat 4763 4764 Input Parameters: 4765 . mat - the matrix 4766 4767 Output Parameter: 4768 . v - the vector for storing the sum of rows 4769 4770 Level: intermediate 4771 4772 Notes: 4773 This code is slow since it is not currently specialized for different formats 4774 4775 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4776 @*/ 4777 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4778 { 4779 Vec ones; 4780 PetscErrorCode ierr; 4781 4782 PetscFunctionBegin; 4783 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4784 PetscValidType(mat,1); 4785 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4786 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4787 MatCheckPreallocated(mat,1); 4788 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4789 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4790 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4791 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4792 PetscFunctionReturn(0); 4793 } 4794 4795 /*@ 4796 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4797 4798 Collective on Mat 4799 4800 Input Parameter: 4801 + mat - the matrix to transpose 4802 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4803 4804 Output Parameters: 4805 . B - the transpose 4806 4807 Notes: 4808 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4809 4810 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4811 4812 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4813 4814 Level: intermediate 4815 4816 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4817 @*/ 4818 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4819 { 4820 PetscErrorCode ierr; 4821 4822 PetscFunctionBegin; 4823 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4824 PetscValidType(mat,1); 4825 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4826 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4827 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4828 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4829 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4830 MatCheckPreallocated(mat,1); 4831 4832 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4833 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4834 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4835 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4836 PetscFunctionReturn(0); 4837 } 4838 4839 /*@ 4840 MatIsTranspose - Test whether a matrix is another one's transpose, 4841 or its own, in which case it tests symmetry. 4842 4843 Collective on Mat 4844 4845 Input Parameter: 4846 + A - the matrix to test 4847 - B - the matrix to test against, this can equal the first parameter 4848 4849 Output Parameters: 4850 . flg - the result 4851 4852 Notes: 4853 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4854 has a running time of the order of the number of nonzeros; the parallel 4855 test involves parallel copies of the block-offdiagonal parts of the matrix. 4856 4857 Level: intermediate 4858 4859 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4860 @*/ 4861 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4862 { 4863 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4864 4865 PetscFunctionBegin; 4866 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4867 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4868 PetscValidBoolPointer(flg,3); 4869 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4870 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4871 *flg = PETSC_FALSE; 4872 if (f && g) { 4873 if (f == g) { 4874 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4875 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4876 } else { 4877 MatType mattype; 4878 if (!f) { 4879 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4880 } else { 4881 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4882 } 4883 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4884 } 4885 PetscFunctionReturn(0); 4886 } 4887 4888 /*@ 4889 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4890 4891 Collective on Mat 4892 4893 Input Parameter: 4894 + mat - the matrix to transpose and complex conjugate 4895 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4896 4897 Output Parameters: 4898 . B - the Hermitian 4899 4900 Level: intermediate 4901 4902 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4903 @*/ 4904 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4905 { 4906 PetscErrorCode ierr; 4907 4908 PetscFunctionBegin; 4909 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4910 #if defined(PETSC_USE_COMPLEX) 4911 ierr = MatConjugate(*B);CHKERRQ(ierr); 4912 #endif 4913 PetscFunctionReturn(0); 4914 } 4915 4916 /*@ 4917 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4918 4919 Collective on Mat 4920 4921 Input Parameter: 4922 + A - the matrix to test 4923 - B - the matrix to test against, this can equal the first parameter 4924 4925 Output Parameters: 4926 . flg - the result 4927 4928 Notes: 4929 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4930 has a running time of the order of the number of nonzeros; the parallel 4931 test involves parallel copies of the block-offdiagonal parts of the matrix. 4932 4933 Level: intermediate 4934 4935 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4936 @*/ 4937 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4938 { 4939 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4940 4941 PetscFunctionBegin; 4942 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4943 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4944 PetscValidBoolPointer(flg,3); 4945 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4946 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4947 if (f && g) { 4948 if (f==g) { 4949 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4950 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4951 } 4952 PetscFunctionReturn(0); 4953 } 4954 4955 /*@ 4956 MatPermute - Creates a new matrix with rows and columns permuted from the 4957 original. 4958 4959 Collective on Mat 4960 4961 Input Parameters: 4962 + mat - the matrix to permute 4963 . row - row permutation, each processor supplies only the permutation for its rows 4964 - col - column permutation, each processor supplies only the permutation for its columns 4965 4966 Output Parameters: 4967 . B - the permuted matrix 4968 4969 Level: advanced 4970 4971 Note: 4972 The index sets map from row/col of permuted matrix to row/col of original matrix. 4973 The index sets should be on the same communicator as Mat and have the same local sizes. 4974 4975 .seealso: MatGetOrdering(), ISAllGather() 4976 4977 @*/ 4978 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4979 { 4980 PetscErrorCode ierr; 4981 4982 PetscFunctionBegin; 4983 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4984 PetscValidType(mat,1); 4985 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4986 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4987 PetscValidPointer(B,4); 4988 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4989 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4990 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4991 MatCheckPreallocated(mat,1); 4992 4993 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 4994 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 4995 PetscFunctionReturn(0); 4996 } 4997 4998 /*@ 4999 MatEqual - Compares two matrices. 5000 5001 Collective on Mat 5002 5003 Input Parameters: 5004 + A - the first matrix 5005 - B - the second matrix 5006 5007 Output Parameter: 5008 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5009 5010 Level: intermediate 5011 5012 @*/ 5013 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5014 { 5015 PetscErrorCode ierr; 5016 5017 PetscFunctionBegin; 5018 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5019 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5020 PetscValidType(A,1); 5021 PetscValidType(B,2); 5022 PetscValidBoolPointer(flg,3); 5023 PetscCheckSameComm(A,1,B,2); 5024 MatCheckPreallocated(B,2); 5025 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5026 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5027 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); 5028 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5029 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5030 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); 5031 MatCheckPreallocated(A,1); 5032 5033 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5034 PetscFunctionReturn(0); 5035 } 5036 5037 /*@ 5038 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5039 matrices that are stored as vectors. Either of the two scaling 5040 matrices can be NULL. 5041 5042 Collective on Mat 5043 5044 Input Parameters: 5045 + mat - the matrix to be scaled 5046 . l - the left scaling vector (or NULL) 5047 - r - the right scaling vector (or NULL) 5048 5049 Notes: 5050 MatDiagonalScale() computes A = LAR, where 5051 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5052 The L scales the rows of the matrix, the R scales the columns of the matrix. 5053 5054 Level: intermediate 5055 5056 5057 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5058 @*/ 5059 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5060 { 5061 PetscErrorCode ierr; 5062 5063 PetscFunctionBegin; 5064 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5065 PetscValidType(mat,1); 5066 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5067 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5068 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5069 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5070 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5071 MatCheckPreallocated(mat,1); 5072 5073 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5074 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5075 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5076 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5077 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5078 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5079 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5080 } 5081 #endif 5082 PetscFunctionReturn(0); 5083 } 5084 5085 /*@ 5086 MatScale - Scales all elements of a matrix by a given number. 5087 5088 Logically Collective on Mat 5089 5090 Input Parameters: 5091 + mat - the matrix to be scaled 5092 - a - the scaling value 5093 5094 Output Parameter: 5095 . mat - the scaled matrix 5096 5097 Level: intermediate 5098 5099 .seealso: MatDiagonalScale() 5100 @*/ 5101 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5102 { 5103 PetscErrorCode ierr; 5104 5105 PetscFunctionBegin; 5106 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5107 PetscValidType(mat,1); 5108 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5109 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5110 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5111 PetscValidLogicalCollectiveScalar(mat,a,2); 5112 MatCheckPreallocated(mat,1); 5113 5114 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5115 if (a != (PetscScalar)1.0) { 5116 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5117 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5118 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5119 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5120 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5121 } 5122 #endif 5123 } 5124 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5125 PetscFunctionReturn(0); 5126 } 5127 5128 /*@ 5129 MatNorm - Calculates various norms of a matrix. 5130 5131 Collective on Mat 5132 5133 Input Parameters: 5134 + mat - the matrix 5135 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5136 5137 Output Parameters: 5138 . nrm - the resulting norm 5139 5140 Level: intermediate 5141 5142 @*/ 5143 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5144 { 5145 PetscErrorCode ierr; 5146 5147 PetscFunctionBegin; 5148 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5149 PetscValidType(mat,1); 5150 PetscValidScalarPointer(nrm,3); 5151 5152 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5153 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5154 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5155 MatCheckPreallocated(mat,1); 5156 5157 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5158 PetscFunctionReturn(0); 5159 } 5160 5161 /* 5162 This variable is used to prevent counting of MatAssemblyBegin() that 5163 are called from within a MatAssemblyEnd(). 5164 */ 5165 static PetscInt MatAssemblyEnd_InUse = 0; 5166 /*@ 5167 MatAssemblyBegin - Begins assembling the matrix. This routine should 5168 be called after completing all calls to MatSetValues(). 5169 5170 Collective on Mat 5171 5172 Input Parameters: 5173 + mat - the matrix 5174 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5175 5176 Notes: 5177 MatSetValues() generally caches the values. The matrix is ready to 5178 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5179 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5180 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5181 using the matrix. 5182 5183 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5184 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 5185 a global collective operation requring all processes that share the matrix. 5186 5187 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5188 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5189 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5190 5191 Level: beginner 5192 5193 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5194 @*/ 5195 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5196 { 5197 PetscErrorCode ierr; 5198 5199 PetscFunctionBegin; 5200 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5201 PetscValidType(mat,1); 5202 MatCheckPreallocated(mat,1); 5203 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5204 if (mat->assembled) { 5205 mat->was_assembled = PETSC_TRUE; 5206 mat->assembled = PETSC_FALSE; 5207 } 5208 5209 if (!MatAssemblyEnd_InUse) { 5210 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5211 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5212 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5213 } else if (mat->ops->assemblybegin) { 5214 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5215 } 5216 PetscFunctionReturn(0); 5217 } 5218 5219 /*@ 5220 MatAssembled - Indicates if a matrix has been assembled and is ready for 5221 use; for example, in matrix-vector product. 5222 5223 Not Collective 5224 5225 Input Parameter: 5226 . mat - the matrix 5227 5228 Output Parameter: 5229 . assembled - PETSC_TRUE or PETSC_FALSE 5230 5231 Level: advanced 5232 5233 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5234 @*/ 5235 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5236 { 5237 PetscFunctionBegin; 5238 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5239 PetscValidPointer(assembled,2); 5240 *assembled = mat->assembled; 5241 PetscFunctionReturn(0); 5242 } 5243 5244 /*@ 5245 MatAssemblyEnd - Completes assembling the matrix. This routine should 5246 be called after MatAssemblyBegin(). 5247 5248 Collective on Mat 5249 5250 Input Parameters: 5251 + mat - the matrix 5252 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5253 5254 Options Database Keys: 5255 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5256 . -mat_view ::ascii_info_detail - Prints more detailed info 5257 . -mat_view - Prints matrix in ASCII format 5258 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5259 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5260 . -display <name> - Sets display name (default is host) 5261 . -draw_pause <sec> - Sets number of seconds to pause after display 5262 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5263 . -viewer_socket_machine <machine> - Machine to use for socket 5264 . -viewer_socket_port <port> - Port number to use for socket 5265 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5266 5267 Notes: 5268 MatSetValues() generally caches the values. The matrix is ready to 5269 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5270 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5271 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5272 using the matrix. 5273 5274 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5275 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5276 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5277 5278 Level: beginner 5279 5280 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5281 @*/ 5282 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5283 { 5284 PetscErrorCode ierr; 5285 static PetscInt inassm = 0; 5286 PetscBool flg = PETSC_FALSE; 5287 5288 PetscFunctionBegin; 5289 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5290 PetscValidType(mat,1); 5291 5292 inassm++; 5293 MatAssemblyEnd_InUse++; 5294 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5295 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5296 if (mat->ops->assemblyend) { 5297 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5298 } 5299 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5300 } else if (mat->ops->assemblyend) { 5301 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5302 } 5303 5304 /* Flush assembly is not a true assembly */ 5305 if (type != MAT_FLUSH_ASSEMBLY) { 5306 mat->assembled = PETSC_TRUE; 5307 mat->num_ass++; 5308 mat->ass_nonzerostate = mat->nonzerostate; 5309 } 5310 5311 mat->insertmode = NOT_SET_VALUES; 5312 MatAssemblyEnd_InUse--; 5313 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5314 if (!mat->symmetric_eternal) { 5315 mat->symmetric_set = PETSC_FALSE; 5316 mat->hermitian_set = PETSC_FALSE; 5317 mat->structurally_symmetric_set = PETSC_FALSE; 5318 } 5319 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5320 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5321 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5322 } 5323 #endif 5324 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5325 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5326 5327 if (mat->checksymmetryonassembly) { 5328 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5329 if (flg) { 5330 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5331 } else { 5332 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5333 } 5334 } 5335 if (mat->nullsp && mat->checknullspaceonassembly) { 5336 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5337 } 5338 } 5339 inassm--; 5340 PetscFunctionReturn(0); 5341 } 5342 5343 /*@ 5344 MatSetOption - Sets a parameter option for a matrix. Some options 5345 may be specific to certain storage formats. Some options 5346 determine how values will be inserted (or added). Sorted, 5347 row-oriented input will generally assemble the fastest. The default 5348 is row-oriented. 5349 5350 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5351 5352 Input Parameters: 5353 + mat - the matrix 5354 . option - the option, one of those listed below (and possibly others), 5355 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5356 5357 Options Describing Matrix Structure: 5358 + MAT_SPD - symmetric positive definite 5359 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5360 . MAT_HERMITIAN - transpose is the complex conjugation 5361 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5362 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5363 you set to be kept with all future use of the matrix 5364 including after MatAssemblyBegin/End() which could 5365 potentially change the symmetry structure, i.e. you 5366 KNOW the matrix will ALWAYS have the property you set. 5367 5368 5369 Options For Use with MatSetValues(): 5370 Insert a logically dense subblock, which can be 5371 . MAT_ROW_ORIENTED - row-oriented (default) 5372 5373 Note these options reflect the data you pass in with MatSetValues(); it has 5374 nothing to do with how the data is stored internally in the matrix 5375 data structure. 5376 5377 When (re)assembling a matrix, we can restrict the input for 5378 efficiency/debugging purposes. These options include: 5379 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5380 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5381 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5382 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5383 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5384 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5385 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5386 performance for very large process counts. 5387 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5388 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5389 functions, instead sending only neighbor messages. 5390 5391 Notes: 5392 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5393 5394 Some options are relevant only for particular matrix types and 5395 are thus ignored by others. Other options are not supported by 5396 certain matrix types and will generate an error message if set. 5397 5398 If using a Fortran 77 module to compute a matrix, one may need to 5399 use the column-oriented option (or convert to the row-oriented 5400 format). 5401 5402 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5403 that would generate a new entry in the nonzero structure is instead 5404 ignored. Thus, if memory has not alredy been allocated for this particular 5405 data, then the insertion is ignored. For dense matrices, in which 5406 the entire array is allocated, no entries are ever ignored. 5407 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5408 5409 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5410 that would generate a new entry in the nonzero structure instead produces 5411 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 5412 5413 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5414 that would generate a new entry that has not been preallocated will 5415 instead produce an error. (Currently supported for AIJ and BAIJ formats 5416 only.) This is a useful flag when debugging matrix memory preallocation. 5417 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5418 5419 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5420 other processors should be dropped, rather than stashed. 5421 This is useful if you know that the "owning" processor is also 5422 always generating the correct matrix entries, so that PETSc need 5423 not transfer duplicate entries generated on another processor. 5424 5425 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5426 searches during matrix assembly. When this flag is set, the hash table 5427 is created during the first Matrix Assembly. This hash table is 5428 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5429 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5430 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5431 supported by MATMPIBAIJ format only. 5432 5433 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5434 are kept in the nonzero structure 5435 5436 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5437 a zero location in the matrix 5438 5439 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5440 5441 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5442 zero row routines and thus improves performance for very large process counts. 5443 5444 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5445 part of the matrix (since they should match the upper triangular part). 5446 5447 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5448 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5449 with finite difference schemes with non-periodic boundary conditions. 5450 Notes: 5451 Can only be called after MatSetSizes() and MatSetType() have been set. 5452 5453 Level: intermediate 5454 5455 .seealso: MatOption, Mat 5456 5457 @*/ 5458 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5459 { 5460 PetscErrorCode ierr; 5461 5462 PetscFunctionBegin; 5463 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5464 PetscValidType(mat,1); 5465 if (op > 0) { 5466 PetscValidLogicalCollectiveEnum(mat,op,2); 5467 PetscValidLogicalCollectiveBool(mat,flg,3); 5468 } 5469 5470 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); 5471 if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()"); 5472 5473 switch (op) { 5474 case MAT_NO_OFF_PROC_ENTRIES: 5475 mat->nooffprocentries = flg; 5476 PetscFunctionReturn(0); 5477 break; 5478 case MAT_SUBSET_OFF_PROC_ENTRIES: 5479 mat->assembly_subset = flg; 5480 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5481 #if !defined(PETSC_HAVE_MPIUNI) 5482 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5483 #endif 5484 mat->stash.first_assembly_done = PETSC_FALSE; 5485 } 5486 PetscFunctionReturn(0); 5487 case MAT_NO_OFF_PROC_ZERO_ROWS: 5488 mat->nooffproczerorows = flg; 5489 PetscFunctionReturn(0); 5490 break; 5491 case MAT_SPD: 5492 mat->spd_set = PETSC_TRUE; 5493 mat->spd = flg; 5494 if (flg) { 5495 mat->symmetric = PETSC_TRUE; 5496 mat->structurally_symmetric = PETSC_TRUE; 5497 mat->symmetric_set = PETSC_TRUE; 5498 mat->structurally_symmetric_set = PETSC_TRUE; 5499 } 5500 break; 5501 case MAT_SYMMETRIC: 5502 mat->symmetric = flg; 5503 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5504 mat->symmetric_set = PETSC_TRUE; 5505 mat->structurally_symmetric_set = flg; 5506 #if !defined(PETSC_USE_COMPLEX) 5507 mat->hermitian = flg; 5508 mat->hermitian_set = PETSC_TRUE; 5509 #endif 5510 break; 5511 case MAT_HERMITIAN: 5512 mat->hermitian = flg; 5513 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5514 mat->hermitian_set = PETSC_TRUE; 5515 mat->structurally_symmetric_set = flg; 5516 #if !defined(PETSC_USE_COMPLEX) 5517 mat->symmetric = flg; 5518 mat->symmetric_set = PETSC_TRUE; 5519 #endif 5520 break; 5521 case MAT_STRUCTURALLY_SYMMETRIC: 5522 mat->structurally_symmetric = flg; 5523 mat->structurally_symmetric_set = PETSC_TRUE; 5524 break; 5525 case MAT_SYMMETRY_ETERNAL: 5526 mat->symmetric_eternal = flg; 5527 break; 5528 case MAT_STRUCTURE_ONLY: 5529 mat->structure_only = flg; 5530 break; 5531 case MAT_SORTED_FULL: 5532 mat->sortedfull = flg; 5533 break; 5534 default: 5535 break; 5536 } 5537 if (mat->ops->setoption) { 5538 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5539 } 5540 PetscFunctionReturn(0); 5541 } 5542 5543 /*@ 5544 MatGetOption - Gets a parameter option that has been set for a matrix. 5545 5546 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5547 5548 Input Parameters: 5549 + mat - the matrix 5550 - option - the option, this only responds to certain options, check the code for which ones 5551 5552 Output Parameter: 5553 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5554 5555 Notes: 5556 Can only be called after MatSetSizes() and MatSetType() have been set. 5557 5558 Level: intermediate 5559 5560 .seealso: MatOption, MatSetOption() 5561 5562 @*/ 5563 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5564 { 5565 PetscFunctionBegin; 5566 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5567 PetscValidType(mat,1); 5568 5569 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); 5570 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()"); 5571 5572 switch (op) { 5573 case MAT_NO_OFF_PROC_ENTRIES: 5574 *flg = mat->nooffprocentries; 5575 break; 5576 case MAT_NO_OFF_PROC_ZERO_ROWS: 5577 *flg = mat->nooffproczerorows; 5578 break; 5579 case MAT_SYMMETRIC: 5580 *flg = mat->symmetric; 5581 break; 5582 case MAT_HERMITIAN: 5583 *flg = mat->hermitian; 5584 break; 5585 case MAT_STRUCTURALLY_SYMMETRIC: 5586 *flg = mat->structurally_symmetric; 5587 break; 5588 case MAT_SYMMETRY_ETERNAL: 5589 *flg = mat->symmetric_eternal; 5590 break; 5591 case MAT_SPD: 5592 *flg = mat->spd; 5593 break; 5594 default: 5595 break; 5596 } 5597 PetscFunctionReturn(0); 5598 } 5599 5600 /*@ 5601 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5602 this routine retains the old nonzero structure. 5603 5604 Logically Collective on Mat 5605 5606 Input Parameters: 5607 . mat - the matrix 5608 5609 Level: intermediate 5610 5611 Notes: 5612 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. 5613 See the Performance chapter of the users manual for information on preallocating matrices. 5614 5615 .seealso: MatZeroRows() 5616 @*/ 5617 PetscErrorCode MatZeroEntries(Mat mat) 5618 { 5619 PetscErrorCode ierr; 5620 5621 PetscFunctionBegin; 5622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5623 PetscValidType(mat,1); 5624 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5625 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"); 5626 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5627 MatCheckPreallocated(mat,1); 5628 5629 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5630 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5631 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5632 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5633 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5634 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5635 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5636 } 5637 #endif 5638 PetscFunctionReturn(0); 5639 } 5640 5641 /*@ 5642 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5643 of a set of rows and columns of a matrix. 5644 5645 Collective on Mat 5646 5647 Input Parameters: 5648 + mat - the matrix 5649 . numRows - the number of rows to remove 5650 . rows - the global row indices 5651 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5652 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5653 - b - optional vector of right hand side, that will be adjusted by provided solution 5654 5655 Notes: 5656 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5657 5658 The user can set a value in the diagonal entry (or for the AIJ and 5659 row formats can optionally remove the main diagonal entry from the 5660 nonzero structure as well, by passing 0.0 as the final argument). 5661 5662 For the parallel case, all processes that share the matrix (i.e., 5663 those in the communicator used for matrix creation) MUST call this 5664 routine, regardless of whether any rows being zeroed are owned by 5665 them. 5666 5667 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5668 list only rows local to itself). 5669 5670 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5671 5672 Level: intermediate 5673 5674 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5675 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5676 @*/ 5677 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5678 { 5679 PetscErrorCode ierr; 5680 5681 PetscFunctionBegin; 5682 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5683 PetscValidType(mat,1); 5684 if (numRows) PetscValidIntPointer(rows,3); 5685 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5686 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5687 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5688 MatCheckPreallocated(mat,1); 5689 5690 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5691 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5692 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5693 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5694 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5695 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5696 } 5697 #endif 5698 PetscFunctionReturn(0); 5699 } 5700 5701 /*@ 5702 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5703 of a set of rows and columns of a matrix. 5704 5705 Collective on Mat 5706 5707 Input Parameters: 5708 + mat - the matrix 5709 . is - the rows to zero 5710 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5711 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5712 - b - optional vector of right hand side, that will be adjusted by provided solution 5713 5714 Notes: 5715 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5716 5717 The user can set a value in the diagonal entry (or for the AIJ and 5718 row formats can optionally remove the main diagonal entry from the 5719 nonzero structure as well, by passing 0.0 as the final argument). 5720 5721 For the parallel case, all processes that share the matrix (i.e., 5722 those in the communicator used for matrix creation) MUST call this 5723 routine, regardless of whether any rows being zeroed are owned by 5724 them. 5725 5726 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5727 list only rows local to itself). 5728 5729 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5730 5731 Level: intermediate 5732 5733 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5734 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5735 @*/ 5736 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5737 { 5738 PetscErrorCode ierr; 5739 PetscInt numRows; 5740 const PetscInt *rows; 5741 5742 PetscFunctionBegin; 5743 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5744 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5745 PetscValidType(mat,1); 5746 PetscValidType(is,2); 5747 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5748 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5749 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5750 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5751 PetscFunctionReturn(0); 5752 } 5753 5754 /*@ 5755 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5756 of a set of rows of a matrix. 5757 5758 Collective on Mat 5759 5760 Input Parameters: 5761 + mat - the matrix 5762 . numRows - the number of rows to remove 5763 . rows - the global row indices 5764 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5765 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5766 - b - optional vector of right hand side, that will be adjusted by provided solution 5767 5768 Notes: 5769 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5770 but does not release memory. For the dense and block diagonal 5771 formats this does not alter the nonzero structure. 5772 5773 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5774 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5775 merely zeroed. 5776 5777 The user can set a value in the diagonal entry (or for the AIJ and 5778 row formats can optionally remove the main diagonal entry from the 5779 nonzero structure as well, by passing 0.0 as the final argument). 5780 5781 For the parallel case, all processes that share the matrix (i.e., 5782 those in the communicator used for matrix creation) MUST call this 5783 routine, regardless of whether any rows being zeroed are owned by 5784 them. 5785 5786 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5787 list only rows local to itself). 5788 5789 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5790 owns that are to be zeroed. This saves a global synchronization in the implementation. 5791 5792 Level: intermediate 5793 5794 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5795 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5796 @*/ 5797 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5798 { 5799 PetscErrorCode ierr; 5800 5801 PetscFunctionBegin; 5802 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5803 PetscValidType(mat,1); 5804 if (numRows) PetscValidIntPointer(rows,3); 5805 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5806 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5807 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5808 MatCheckPreallocated(mat,1); 5809 5810 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5811 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5812 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5813 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5814 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5815 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5816 } 5817 #endif 5818 PetscFunctionReturn(0); 5819 } 5820 5821 /*@ 5822 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5823 of a set of rows of a matrix. 5824 5825 Collective on Mat 5826 5827 Input Parameters: 5828 + mat - the matrix 5829 . is - index set of rows to remove 5830 . diag - value put in all diagonals of eliminated rows 5831 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5832 - b - optional vector of right hand side, that will be adjusted by provided solution 5833 5834 Notes: 5835 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5836 but does not release memory. For the dense and block diagonal 5837 formats this does not alter the nonzero structure. 5838 5839 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5840 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5841 merely zeroed. 5842 5843 The user can set a value in the diagonal entry (or for the AIJ and 5844 row formats can optionally remove the main diagonal entry from the 5845 nonzero structure as well, by passing 0.0 as the final argument). 5846 5847 For the parallel case, all processes that share the matrix (i.e., 5848 those in the communicator used for matrix creation) MUST call this 5849 routine, regardless of whether any rows being zeroed are owned by 5850 them. 5851 5852 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5853 list only rows local to itself). 5854 5855 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5856 owns that are to be zeroed. This saves a global synchronization in the implementation. 5857 5858 Level: intermediate 5859 5860 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5861 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5862 @*/ 5863 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5864 { 5865 PetscInt numRows; 5866 const PetscInt *rows; 5867 PetscErrorCode ierr; 5868 5869 PetscFunctionBegin; 5870 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5871 PetscValidType(mat,1); 5872 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5873 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5874 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5875 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5876 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5877 PetscFunctionReturn(0); 5878 } 5879 5880 /*@ 5881 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5882 of a set of rows of a matrix. These rows must be local to the process. 5883 5884 Collective on Mat 5885 5886 Input Parameters: 5887 + mat - the matrix 5888 . numRows - the number of rows to remove 5889 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5890 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5891 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5892 - b - optional vector of right hand side, that will be adjusted by provided solution 5893 5894 Notes: 5895 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5896 but does not release memory. For the dense and block diagonal 5897 formats this does not alter the nonzero structure. 5898 5899 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5900 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5901 merely zeroed. 5902 5903 The user can set a value in the diagonal entry (or for the AIJ and 5904 row formats can optionally remove the main diagonal entry from the 5905 nonzero structure as well, by passing 0.0 as the final argument). 5906 5907 For the parallel case, all processes that share the matrix (i.e., 5908 those in the communicator used for matrix creation) MUST call this 5909 routine, regardless of whether any rows being zeroed are owned by 5910 them. 5911 5912 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5913 list only rows local to itself). 5914 5915 The grid coordinates are across the entire grid, not just the local portion 5916 5917 In Fortran idxm and idxn should be declared as 5918 $ MatStencil idxm(4,m) 5919 and the values inserted using 5920 $ idxm(MatStencil_i,1) = i 5921 $ idxm(MatStencil_j,1) = j 5922 $ idxm(MatStencil_k,1) = k 5923 $ idxm(MatStencil_c,1) = c 5924 etc 5925 5926 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5927 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5928 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5929 DM_BOUNDARY_PERIODIC boundary type. 5930 5931 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 5932 a single value per point) you can skip filling those indices. 5933 5934 Level: intermediate 5935 5936 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5937 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5938 @*/ 5939 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5940 { 5941 PetscInt dim = mat->stencil.dim; 5942 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5943 PetscInt *dims = mat->stencil.dims+1; 5944 PetscInt *starts = mat->stencil.starts; 5945 PetscInt *dxm = (PetscInt*) rows; 5946 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5947 PetscErrorCode ierr; 5948 5949 PetscFunctionBegin; 5950 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5951 PetscValidType(mat,1); 5952 if (numRows) PetscValidIntPointer(rows,3); 5953 5954 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 5955 for (i = 0; i < numRows; ++i) { 5956 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5957 for (j = 0; j < 3-sdim; ++j) dxm++; 5958 /* Local index in X dir */ 5959 tmp = *dxm++ - starts[0]; 5960 /* Loop over remaining dimensions */ 5961 for (j = 0; j < dim-1; ++j) { 5962 /* If nonlocal, set index to be negative */ 5963 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5964 /* Update local index */ 5965 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5966 } 5967 /* Skip component slot if necessary */ 5968 if (mat->stencil.noc) dxm++; 5969 /* Local row number */ 5970 if (tmp >= 0) { 5971 jdxm[numNewRows++] = tmp; 5972 } 5973 } 5974 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5975 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5976 PetscFunctionReturn(0); 5977 } 5978 5979 /*@ 5980 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5981 of a set of rows and columns of a matrix. 5982 5983 Collective on Mat 5984 5985 Input Parameters: 5986 + mat - the matrix 5987 . numRows - the number of rows/columns to remove 5988 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5989 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5990 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5991 - b - optional vector of right hand side, that will be adjusted by provided solution 5992 5993 Notes: 5994 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5995 but does not release memory. For the dense and block diagonal 5996 formats this does not alter the nonzero structure. 5997 5998 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5999 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6000 merely zeroed. 6001 6002 The user can set a value in the diagonal entry (or for the AIJ and 6003 row formats can optionally remove the main diagonal entry from the 6004 nonzero structure as well, by passing 0.0 as the final argument). 6005 6006 For the parallel case, all processes that share the matrix (i.e., 6007 those in the communicator used for matrix creation) MUST call this 6008 routine, regardless of whether any rows being zeroed are owned by 6009 them. 6010 6011 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6012 list only rows local to itself, but the row/column numbers are given in local numbering). 6013 6014 The grid coordinates are across the entire grid, not just the local portion 6015 6016 In Fortran idxm and idxn should be declared as 6017 $ MatStencil idxm(4,m) 6018 and the values inserted using 6019 $ idxm(MatStencil_i,1) = i 6020 $ idxm(MatStencil_j,1) = j 6021 $ idxm(MatStencil_k,1) = k 6022 $ idxm(MatStencil_c,1) = c 6023 etc 6024 6025 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6026 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6027 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6028 DM_BOUNDARY_PERIODIC boundary type. 6029 6030 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 6031 a single value per point) you can skip filling those indices. 6032 6033 Level: intermediate 6034 6035 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6036 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6037 @*/ 6038 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6039 { 6040 PetscInt dim = mat->stencil.dim; 6041 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6042 PetscInt *dims = mat->stencil.dims+1; 6043 PetscInt *starts = mat->stencil.starts; 6044 PetscInt *dxm = (PetscInt*) rows; 6045 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6046 PetscErrorCode ierr; 6047 6048 PetscFunctionBegin; 6049 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6050 PetscValidType(mat,1); 6051 if (numRows) PetscValidIntPointer(rows,3); 6052 6053 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6054 for (i = 0; i < numRows; ++i) { 6055 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6056 for (j = 0; j < 3-sdim; ++j) dxm++; 6057 /* Local index in X dir */ 6058 tmp = *dxm++ - starts[0]; 6059 /* Loop over remaining dimensions */ 6060 for (j = 0; j < dim-1; ++j) { 6061 /* If nonlocal, set index to be negative */ 6062 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6063 /* Update local index */ 6064 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6065 } 6066 /* Skip component slot if necessary */ 6067 if (mat->stencil.noc) dxm++; 6068 /* Local row number */ 6069 if (tmp >= 0) { 6070 jdxm[numNewRows++] = tmp; 6071 } 6072 } 6073 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6074 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6075 PetscFunctionReturn(0); 6076 } 6077 6078 /*@C 6079 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6080 of a set of rows of a matrix; using local numbering of rows. 6081 6082 Collective on Mat 6083 6084 Input Parameters: 6085 + mat - the matrix 6086 . numRows - the number of rows to remove 6087 . rows - the global row indices 6088 . diag - value put in all diagonals of eliminated rows 6089 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6090 - b - optional vector of right hand side, that will be adjusted by provided solution 6091 6092 Notes: 6093 Before calling MatZeroRowsLocal(), the user must first set the 6094 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6095 6096 For the AIJ matrix formats this removes the old nonzero structure, 6097 but does not release memory. For the dense and block diagonal 6098 formats this does not alter the nonzero structure. 6099 6100 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6101 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6102 merely zeroed. 6103 6104 The user can set a value in the diagonal entry (or for the AIJ and 6105 row formats can optionally remove the main diagonal entry from the 6106 nonzero structure as well, by passing 0.0 as the final argument). 6107 6108 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6109 owns that are to be zeroed. This saves a global synchronization in the implementation. 6110 6111 Level: intermediate 6112 6113 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6114 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6115 @*/ 6116 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6117 { 6118 PetscErrorCode ierr; 6119 6120 PetscFunctionBegin; 6121 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6122 PetscValidType(mat,1); 6123 if (numRows) PetscValidIntPointer(rows,3); 6124 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6125 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6126 MatCheckPreallocated(mat,1); 6127 6128 if (mat->ops->zerorowslocal) { 6129 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6130 } else { 6131 IS is, newis; 6132 const PetscInt *newRows; 6133 6134 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6135 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6136 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6137 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6138 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6139 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6140 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6141 ierr = ISDestroy(&is);CHKERRQ(ierr); 6142 } 6143 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6144 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6145 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6146 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6147 } 6148 #endif 6149 PetscFunctionReturn(0); 6150 } 6151 6152 /*@ 6153 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6154 of a set of rows of a matrix; using local numbering of rows. 6155 6156 Collective on Mat 6157 6158 Input Parameters: 6159 + mat - the matrix 6160 . is - index set of rows to remove 6161 . diag - value put in all diagonals of eliminated rows 6162 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6163 - b - optional vector of right hand side, that will be adjusted by provided solution 6164 6165 Notes: 6166 Before calling MatZeroRowsLocalIS(), the user must first set the 6167 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6168 6169 For the AIJ matrix formats this removes the old nonzero structure, 6170 but does not release memory. For the dense and block diagonal 6171 formats this does not alter the nonzero structure. 6172 6173 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6174 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6175 merely zeroed. 6176 6177 The user can set a value in the diagonal entry (or for the AIJ and 6178 row formats can optionally remove the main diagonal entry from the 6179 nonzero structure as well, by passing 0.0 as the final argument). 6180 6181 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6182 owns that are to be zeroed. This saves a global synchronization in the implementation. 6183 6184 Level: intermediate 6185 6186 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6187 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6188 @*/ 6189 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6190 { 6191 PetscErrorCode ierr; 6192 PetscInt numRows; 6193 const PetscInt *rows; 6194 6195 PetscFunctionBegin; 6196 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6197 PetscValidType(mat,1); 6198 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6199 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6200 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6201 MatCheckPreallocated(mat,1); 6202 6203 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6204 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6205 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6206 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6207 PetscFunctionReturn(0); 6208 } 6209 6210 /*@ 6211 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6212 of a set of rows and columns of a matrix; using local numbering of rows. 6213 6214 Collective on Mat 6215 6216 Input Parameters: 6217 + mat - the matrix 6218 . numRows - the number of rows to remove 6219 . rows - the global row indices 6220 . diag - value put in all diagonals of eliminated rows 6221 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6222 - b - optional vector of right hand side, that will be adjusted by provided solution 6223 6224 Notes: 6225 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6226 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6227 6228 The user can set a value in the diagonal entry (or for the AIJ and 6229 row formats can optionally remove the main diagonal entry from the 6230 nonzero structure as well, by passing 0.0 as the final argument). 6231 6232 Level: intermediate 6233 6234 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6235 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6236 @*/ 6237 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6238 { 6239 PetscErrorCode ierr; 6240 IS is, newis; 6241 const PetscInt *newRows; 6242 6243 PetscFunctionBegin; 6244 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6245 PetscValidType(mat,1); 6246 if (numRows) PetscValidIntPointer(rows,3); 6247 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6248 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6249 MatCheckPreallocated(mat,1); 6250 6251 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6252 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6253 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6254 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6255 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6256 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6257 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6258 ierr = ISDestroy(&is);CHKERRQ(ierr); 6259 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6260 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6261 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6262 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6263 } 6264 #endif 6265 PetscFunctionReturn(0); 6266 } 6267 6268 /*@ 6269 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6270 of a set of rows and columns of a matrix; using local numbering of rows. 6271 6272 Collective on Mat 6273 6274 Input Parameters: 6275 + mat - the matrix 6276 . is - index set of rows to remove 6277 . diag - value put in all diagonals of eliminated rows 6278 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6279 - b - optional vector of right hand side, that will be adjusted by provided solution 6280 6281 Notes: 6282 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6283 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6284 6285 The user can set a value in the diagonal entry (or for the AIJ and 6286 row formats can optionally remove the main diagonal entry from the 6287 nonzero structure as well, by passing 0.0 as the final argument). 6288 6289 Level: intermediate 6290 6291 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6292 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6293 @*/ 6294 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6295 { 6296 PetscErrorCode ierr; 6297 PetscInt numRows; 6298 const PetscInt *rows; 6299 6300 PetscFunctionBegin; 6301 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6302 PetscValidType(mat,1); 6303 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6304 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6305 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6306 MatCheckPreallocated(mat,1); 6307 6308 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6309 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6310 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6311 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6312 PetscFunctionReturn(0); 6313 } 6314 6315 /*@C 6316 MatGetSize - Returns the numbers of rows and columns in a matrix. 6317 6318 Not Collective 6319 6320 Input Parameter: 6321 . mat - the matrix 6322 6323 Output Parameters: 6324 + m - the number of global rows 6325 - n - the number of global columns 6326 6327 Note: both output parameters can be NULL on input. 6328 6329 Level: beginner 6330 6331 .seealso: MatGetLocalSize() 6332 @*/ 6333 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6334 { 6335 PetscFunctionBegin; 6336 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6337 if (m) *m = mat->rmap->N; 6338 if (n) *n = mat->cmap->N; 6339 PetscFunctionReturn(0); 6340 } 6341 6342 /*@C 6343 MatGetLocalSize - Returns the number of rows and columns in a matrix 6344 stored locally. This information may be implementation dependent, so 6345 use with care. 6346 6347 Not Collective 6348 6349 Input Parameters: 6350 . mat - the matrix 6351 6352 Output Parameters: 6353 + m - the number of local rows 6354 - n - the number of local columns 6355 6356 Note: both output parameters can be NULL on input. 6357 6358 Level: beginner 6359 6360 .seealso: MatGetSize() 6361 @*/ 6362 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6363 { 6364 PetscFunctionBegin; 6365 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6366 if (m) PetscValidIntPointer(m,2); 6367 if (n) PetscValidIntPointer(n,3); 6368 if (m) *m = mat->rmap->n; 6369 if (n) *n = mat->cmap->n; 6370 PetscFunctionReturn(0); 6371 } 6372 6373 /*@C 6374 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6375 this processor. (The columns of the "diagonal block") 6376 6377 Not Collective, unless matrix has not been allocated, then collective on Mat 6378 6379 Input Parameters: 6380 . mat - the matrix 6381 6382 Output Parameters: 6383 + m - the global index of the first local column 6384 - n - one more than the global index of the last local column 6385 6386 Notes: 6387 both output parameters can be NULL on input. 6388 6389 Level: developer 6390 6391 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6392 6393 @*/ 6394 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6395 { 6396 PetscFunctionBegin; 6397 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6398 PetscValidType(mat,1); 6399 if (m) PetscValidIntPointer(m,2); 6400 if (n) PetscValidIntPointer(n,3); 6401 MatCheckPreallocated(mat,1); 6402 if (m) *m = mat->cmap->rstart; 6403 if (n) *n = mat->cmap->rend; 6404 PetscFunctionReturn(0); 6405 } 6406 6407 /*@C 6408 MatGetOwnershipRange - Returns the range of matrix rows owned by 6409 this processor, assuming that the matrix is laid out with the first 6410 n1 rows on the first processor, the next n2 rows on the second, etc. 6411 For certain parallel layouts this range may not be well defined. 6412 6413 Not Collective 6414 6415 Input Parameters: 6416 . mat - the matrix 6417 6418 Output Parameters: 6419 + m - the global index of the first local row 6420 - n - one more than the global index of the last local row 6421 6422 Note: Both output parameters can be NULL on input. 6423 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6424 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6425 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6426 6427 Level: beginner 6428 6429 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6430 6431 @*/ 6432 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6433 { 6434 PetscFunctionBegin; 6435 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6436 PetscValidType(mat,1); 6437 if (m) PetscValidIntPointer(m,2); 6438 if (n) PetscValidIntPointer(n,3); 6439 MatCheckPreallocated(mat,1); 6440 if (m) *m = mat->rmap->rstart; 6441 if (n) *n = mat->rmap->rend; 6442 PetscFunctionReturn(0); 6443 } 6444 6445 /*@C 6446 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6447 each process 6448 6449 Not Collective, unless matrix has not been allocated, then collective on Mat 6450 6451 Input Parameters: 6452 . mat - the matrix 6453 6454 Output Parameters: 6455 . ranges - start of each processors portion plus one more than the total length at the end 6456 6457 Level: beginner 6458 6459 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6460 6461 @*/ 6462 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6463 { 6464 PetscErrorCode ierr; 6465 6466 PetscFunctionBegin; 6467 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6468 PetscValidType(mat,1); 6469 MatCheckPreallocated(mat,1); 6470 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6471 PetscFunctionReturn(0); 6472 } 6473 6474 /*@C 6475 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6476 this processor. (The columns of the "diagonal blocks" for each process) 6477 6478 Not Collective, unless matrix has not been allocated, then collective on Mat 6479 6480 Input Parameters: 6481 . mat - the matrix 6482 6483 Output Parameters: 6484 . ranges - start of each processors portion plus one more then the total length at the end 6485 6486 Level: beginner 6487 6488 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6489 6490 @*/ 6491 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6492 { 6493 PetscErrorCode ierr; 6494 6495 PetscFunctionBegin; 6496 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6497 PetscValidType(mat,1); 6498 MatCheckPreallocated(mat,1); 6499 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6500 PetscFunctionReturn(0); 6501 } 6502 6503 /*@C 6504 MatGetOwnershipIS - Get row and column ownership as index sets 6505 6506 Not Collective 6507 6508 Input Arguments: 6509 . A - matrix of type Elemental 6510 6511 Output Arguments: 6512 + rows - rows in which this process owns elements 6513 - cols - columns in which this process owns elements 6514 6515 Level: intermediate 6516 6517 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6518 @*/ 6519 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6520 { 6521 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6522 6523 PetscFunctionBegin; 6524 MatCheckPreallocated(A,1); 6525 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6526 if (f) { 6527 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6528 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6529 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6530 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6531 } 6532 PetscFunctionReturn(0); 6533 } 6534 6535 /*@C 6536 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6537 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6538 to complete the factorization. 6539 6540 Collective on Mat 6541 6542 Input Parameters: 6543 + mat - the matrix 6544 . row - row permutation 6545 . column - column permutation 6546 - info - structure containing 6547 $ levels - number of levels of fill. 6548 $ expected fill - as ratio of original fill. 6549 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6550 missing diagonal entries) 6551 6552 Output Parameters: 6553 . fact - new matrix that has been symbolically factored 6554 6555 Notes: 6556 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6557 6558 Most users should employ the simplified KSP interface for linear solvers 6559 instead of working directly with matrix algebra routines such as this. 6560 See, e.g., KSPCreate(). 6561 6562 Level: developer 6563 6564 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6565 MatGetOrdering(), MatFactorInfo 6566 6567 Note: this uses the definition of level of fill as in Y. Saad, 2003 6568 6569 Developer Note: fortran interface is not autogenerated as the f90 6570 interface defintion cannot be generated correctly [due to MatFactorInfo] 6571 6572 References: 6573 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6574 @*/ 6575 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6576 { 6577 PetscErrorCode ierr; 6578 6579 PetscFunctionBegin; 6580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6581 PetscValidType(mat,1); 6582 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6583 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6584 PetscValidPointer(info,4); 6585 PetscValidPointer(fact,5); 6586 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6587 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6588 if (!(fact)->ops->ilufactorsymbolic) { 6589 MatSolverType spackage; 6590 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6591 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6592 } 6593 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6594 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6595 MatCheckPreallocated(mat,2); 6596 6597 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6598 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6599 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6600 PetscFunctionReturn(0); 6601 } 6602 6603 /*@C 6604 MatICCFactorSymbolic - Performs symbolic incomplete 6605 Cholesky factorization for a symmetric matrix. Use 6606 MatCholeskyFactorNumeric() to complete the factorization. 6607 6608 Collective on Mat 6609 6610 Input Parameters: 6611 + mat - the matrix 6612 . perm - row and column permutation 6613 - info - structure containing 6614 $ levels - number of levels of fill. 6615 $ expected fill - as ratio of original fill. 6616 6617 Output Parameter: 6618 . fact - the factored matrix 6619 6620 Notes: 6621 Most users should employ the KSP interface for linear solvers 6622 instead of working directly with matrix algebra routines such as this. 6623 See, e.g., KSPCreate(). 6624 6625 Level: developer 6626 6627 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6628 6629 Note: this uses the definition of level of fill as in Y. Saad, 2003 6630 6631 Developer Note: fortran interface is not autogenerated as the f90 6632 interface defintion cannot be generated correctly [due to MatFactorInfo] 6633 6634 References: 6635 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6636 @*/ 6637 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6638 { 6639 PetscErrorCode ierr; 6640 6641 PetscFunctionBegin; 6642 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6643 PetscValidType(mat,1); 6644 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6645 PetscValidPointer(info,3); 6646 PetscValidPointer(fact,4); 6647 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6648 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6649 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6650 if (!(fact)->ops->iccfactorsymbolic) { 6651 MatSolverType spackage; 6652 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6653 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6654 } 6655 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6656 MatCheckPreallocated(mat,2); 6657 6658 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6659 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6660 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6661 PetscFunctionReturn(0); 6662 } 6663 6664 /*@C 6665 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6666 points to an array of valid matrices, they may be reused to store the new 6667 submatrices. 6668 6669 Collective on Mat 6670 6671 Input Parameters: 6672 + mat - the matrix 6673 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6674 . irow, icol - index sets of rows and columns to extract 6675 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6676 6677 Output Parameter: 6678 . submat - the array of submatrices 6679 6680 Notes: 6681 MatCreateSubMatrices() can extract ONLY sequential submatrices 6682 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6683 to extract a parallel submatrix. 6684 6685 Some matrix types place restrictions on the row and column 6686 indices, such as that they be sorted or that they be equal to each other. 6687 6688 The index sets may not have duplicate entries. 6689 6690 When extracting submatrices from a parallel matrix, each processor can 6691 form a different submatrix by setting the rows and columns of its 6692 individual index sets according to the local submatrix desired. 6693 6694 When finished using the submatrices, the user should destroy 6695 them with MatDestroySubMatrices(). 6696 6697 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6698 original matrix has not changed from that last call to MatCreateSubMatrices(). 6699 6700 This routine creates the matrices in submat; you should NOT create them before 6701 calling it. It also allocates the array of matrix pointers submat. 6702 6703 For BAIJ matrices the index sets must respect the block structure, that is if they 6704 request one row/column in a block, they must request all rows/columns that are in 6705 that block. For example, if the block size is 2 you cannot request just row 0 and 6706 column 0. 6707 6708 Fortran Note: 6709 The Fortran interface is slightly different from that given below; it 6710 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6711 6712 Level: advanced 6713 6714 6715 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6716 @*/ 6717 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6718 { 6719 PetscErrorCode ierr; 6720 PetscInt i; 6721 PetscBool eq; 6722 6723 PetscFunctionBegin; 6724 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6725 PetscValidType(mat,1); 6726 if (n) { 6727 PetscValidPointer(irow,3); 6728 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6729 PetscValidPointer(icol,4); 6730 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6731 } 6732 PetscValidPointer(submat,6); 6733 if (n && scall == MAT_REUSE_MATRIX) { 6734 PetscValidPointer(*submat,6); 6735 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6736 } 6737 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6738 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6739 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6740 MatCheckPreallocated(mat,1); 6741 6742 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6743 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6744 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6745 for (i=0; i<n; i++) { 6746 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6747 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6748 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6749 if (eq) { 6750 if (mat->symmetric) { 6751 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6752 } else if (mat->hermitian) { 6753 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6754 } else if (mat->structurally_symmetric) { 6755 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6756 } 6757 } 6758 } 6759 } 6760 PetscFunctionReturn(0); 6761 } 6762 6763 /*@C 6764 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6765 6766 Collective on Mat 6767 6768 Input Parameters: 6769 + mat - the matrix 6770 . n - the number of submatrixes to be extracted 6771 . irow, icol - index sets of rows and columns to extract 6772 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6773 6774 Output Parameter: 6775 . submat - the array of submatrices 6776 6777 Level: advanced 6778 6779 6780 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6781 @*/ 6782 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6783 { 6784 PetscErrorCode ierr; 6785 PetscInt i; 6786 PetscBool eq; 6787 6788 PetscFunctionBegin; 6789 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6790 PetscValidType(mat,1); 6791 if (n) { 6792 PetscValidPointer(irow,3); 6793 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6794 PetscValidPointer(icol,4); 6795 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6796 } 6797 PetscValidPointer(submat,6); 6798 if (n && scall == MAT_REUSE_MATRIX) { 6799 PetscValidPointer(*submat,6); 6800 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6801 } 6802 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6803 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6804 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6805 MatCheckPreallocated(mat,1); 6806 6807 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6808 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6809 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6810 for (i=0; i<n; i++) { 6811 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6812 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6813 if (eq) { 6814 if (mat->symmetric) { 6815 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6816 } else if (mat->hermitian) { 6817 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6818 } else if (mat->structurally_symmetric) { 6819 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6820 } 6821 } 6822 } 6823 } 6824 PetscFunctionReturn(0); 6825 } 6826 6827 /*@C 6828 MatDestroyMatrices - Destroys an array of matrices. 6829 6830 Collective on Mat 6831 6832 Input Parameters: 6833 + n - the number of local matrices 6834 - mat - the matrices (note that this is a pointer to the array of matrices) 6835 6836 Level: advanced 6837 6838 Notes: 6839 Frees not only the matrices, but also the array that contains the matrices 6840 In Fortran will not free the array. 6841 6842 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6843 @*/ 6844 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6845 { 6846 PetscErrorCode ierr; 6847 PetscInt i; 6848 6849 PetscFunctionBegin; 6850 if (!*mat) PetscFunctionReturn(0); 6851 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6852 PetscValidPointer(mat,2); 6853 6854 for (i=0; i<n; i++) { 6855 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6856 } 6857 6858 /* memory is allocated even if n = 0 */ 6859 ierr = PetscFree(*mat);CHKERRQ(ierr); 6860 PetscFunctionReturn(0); 6861 } 6862 6863 /*@C 6864 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6865 6866 Collective on Mat 6867 6868 Input Parameters: 6869 + n - the number of local matrices 6870 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6871 sequence of MatCreateSubMatrices()) 6872 6873 Level: advanced 6874 6875 Notes: 6876 Frees not only the matrices, but also the array that contains the matrices 6877 In Fortran will not free the array. 6878 6879 .seealso: MatCreateSubMatrices() 6880 @*/ 6881 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6882 { 6883 PetscErrorCode ierr; 6884 Mat mat0; 6885 6886 PetscFunctionBegin; 6887 if (!*mat) PetscFunctionReturn(0); 6888 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6889 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6890 PetscValidPointer(mat,2); 6891 6892 mat0 = (*mat)[0]; 6893 if (mat0 && mat0->ops->destroysubmatrices) { 6894 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 6895 } else { 6896 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 6897 } 6898 PetscFunctionReturn(0); 6899 } 6900 6901 /*@C 6902 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6903 6904 Collective on Mat 6905 6906 Input Parameters: 6907 . mat - the matrix 6908 6909 Output Parameter: 6910 . matstruct - the sequential matrix with the nonzero structure of mat 6911 6912 Level: intermediate 6913 6914 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6915 @*/ 6916 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6917 { 6918 PetscErrorCode ierr; 6919 6920 PetscFunctionBegin; 6921 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6922 PetscValidPointer(matstruct,2); 6923 6924 PetscValidType(mat,1); 6925 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6926 MatCheckPreallocated(mat,1); 6927 6928 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6929 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6930 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6931 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6932 PetscFunctionReturn(0); 6933 } 6934 6935 /*@C 6936 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6937 6938 Collective on Mat 6939 6940 Input Parameters: 6941 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6942 sequence of MatGetSequentialNonzeroStructure()) 6943 6944 Level: advanced 6945 6946 Notes: 6947 Frees not only the matrices, but also the array that contains the matrices 6948 6949 .seealso: MatGetSeqNonzeroStructure() 6950 @*/ 6951 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6952 { 6953 PetscErrorCode ierr; 6954 6955 PetscFunctionBegin; 6956 PetscValidPointer(mat,1); 6957 ierr = MatDestroy(mat);CHKERRQ(ierr); 6958 PetscFunctionReturn(0); 6959 } 6960 6961 /*@ 6962 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6963 replaces the index sets by larger ones that represent submatrices with 6964 additional overlap. 6965 6966 Collective on Mat 6967 6968 Input Parameters: 6969 + mat - the matrix 6970 . n - the number of index sets 6971 . is - the array of index sets (these index sets will changed during the call) 6972 - ov - the additional overlap requested 6973 6974 Options Database: 6975 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6976 6977 Level: developer 6978 6979 6980 .seealso: MatCreateSubMatrices() 6981 @*/ 6982 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6983 { 6984 PetscErrorCode ierr; 6985 6986 PetscFunctionBegin; 6987 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6988 PetscValidType(mat,1); 6989 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6990 if (n) { 6991 PetscValidPointer(is,3); 6992 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6993 } 6994 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6995 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6996 MatCheckPreallocated(mat,1); 6997 6998 if (!ov) PetscFunctionReturn(0); 6999 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7000 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7001 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7002 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7003 PetscFunctionReturn(0); 7004 } 7005 7006 7007 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7008 7009 /*@ 7010 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7011 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7012 additional overlap. 7013 7014 Collective on Mat 7015 7016 Input Parameters: 7017 + mat - the matrix 7018 . n - the number of index sets 7019 . is - the array of index sets (these index sets will changed during the call) 7020 - ov - the additional overlap requested 7021 7022 Options Database: 7023 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7024 7025 Level: developer 7026 7027 7028 .seealso: MatCreateSubMatrices() 7029 @*/ 7030 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7031 { 7032 PetscInt i; 7033 PetscErrorCode ierr; 7034 7035 PetscFunctionBegin; 7036 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7037 PetscValidType(mat,1); 7038 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7039 if (n) { 7040 PetscValidPointer(is,3); 7041 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7042 } 7043 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7044 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7045 MatCheckPreallocated(mat,1); 7046 if (!ov) PetscFunctionReturn(0); 7047 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7048 for(i=0; i<n; i++){ 7049 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7050 } 7051 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7052 PetscFunctionReturn(0); 7053 } 7054 7055 7056 7057 7058 /*@ 7059 MatGetBlockSize - Returns the matrix block size. 7060 7061 Not Collective 7062 7063 Input Parameter: 7064 . mat - the matrix 7065 7066 Output Parameter: 7067 . bs - block size 7068 7069 Notes: 7070 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7071 7072 If the block size has not been set yet this routine returns 1. 7073 7074 Level: intermediate 7075 7076 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7077 @*/ 7078 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7079 { 7080 PetscFunctionBegin; 7081 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7082 PetscValidIntPointer(bs,2); 7083 *bs = PetscAbs(mat->rmap->bs); 7084 PetscFunctionReturn(0); 7085 } 7086 7087 /*@ 7088 MatGetBlockSizes - Returns the matrix block row and column sizes. 7089 7090 Not Collective 7091 7092 Input Parameter: 7093 . mat - the matrix 7094 7095 Output Parameter: 7096 + rbs - row block size 7097 - cbs - column block size 7098 7099 Notes: 7100 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7101 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7102 7103 If a block size has not been set yet this routine returns 1. 7104 7105 Level: intermediate 7106 7107 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7108 @*/ 7109 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7110 { 7111 PetscFunctionBegin; 7112 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7113 if (rbs) PetscValidIntPointer(rbs,2); 7114 if (cbs) PetscValidIntPointer(cbs,3); 7115 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7116 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7117 PetscFunctionReturn(0); 7118 } 7119 7120 /*@ 7121 MatSetBlockSize - Sets the matrix block size. 7122 7123 Logically Collective on Mat 7124 7125 Input Parameters: 7126 + mat - the matrix 7127 - bs - block size 7128 7129 Notes: 7130 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7131 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7132 7133 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7134 is compatible with the matrix local sizes. 7135 7136 Level: intermediate 7137 7138 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7139 @*/ 7140 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7141 { 7142 PetscErrorCode ierr; 7143 7144 PetscFunctionBegin; 7145 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7146 PetscValidLogicalCollectiveInt(mat,bs,2); 7147 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7148 PetscFunctionReturn(0); 7149 } 7150 7151 /*@ 7152 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7153 7154 Logically Collective on Mat 7155 7156 Input Parameters: 7157 + mat - the matrix 7158 . nblocks - the number of blocks on this process 7159 - bsizes - the block sizes 7160 7161 Notes: 7162 Currently used by PCVPBJACOBI for SeqAIJ matrices 7163 7164 Level: intermediate 7165 7166 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7167 @*/ 7168 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7169 { 7170 PetscErrorCode ierr; 7171 PetscInt i,ncnt = 0, nlocal; 7172 7173 PetscFunctionBegin; 7174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7175 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7176 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7177 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7178 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); 7179 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7180 mat->nblocks = nblocks; 7181 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7182 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr); 7183 PetscFunctionReturn(0); 7184 } 7185 7186 /*@C 7187 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7188 7189 Logically Collective on Mat 7190 7191 Input Parameters: 7192 . mat - the matrix 7193 7194 Output Parameters: 7195 + nblocks - the number of blocks on this process 7196 - bsizes - the block sizes 7197 7198 Notes: Currently not supported from Fortran 7199 7200 Level: intermediate 7201 7202 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7203 @*/ 7204 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7205 { 7206 PetscFunctionBegin; 7207 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7208 *nblocks = mat->nblocks; 7209 *bsizes = mat->bsizes; 7210 PetscFunctionReturn(0); 7211 } 7212 7213 /*@ 7214 MatSetBlockSizes - Sets the matrix block row and column sizes. 7215 7216 Logically Collective on Mat 7217 7218 Input Parameters: 7219 + mat - the matrix 7220 - rbs - row block size 7221 - cbs - column block size 7222 7223 Notes: 7224 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7225 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7226 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7227 7228 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7229 are compatible with the matrix local sizes. 7230 7231 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7232 7233 Level: intermediate 7234 7235 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7236 @*/ 7237 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7238 { 7239 PetscErrorCode ierr; 7240 7241 PetscFunctionBegin; 7242 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7243 PetscValidLogicalCollectiveInt(mat,rbs,2); 7244 PetscValidLogicalCollectiveInt(mat,cbs,3); 7245 if (mat->ops->setblocksizes) { 7246 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7247 } 7248 if (mat->rmap->refcnt) { 7249 ISLocalToGlobalMapping l2g = NULL; 7250 PetscLayout nmap = NULL; 7251 7252 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7253 if (mat->rmap->mapping) { 7254 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7255 } 7256 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7257 mat->rmap = nmap; 7258 mat->rmap->mapping = l2g; 7259 } 7260 if (mat->cmap->refcnt) { 7261 ISLocalToGlobalMapping l2g = NULL; 7262 PetscLayout nmap = NULL; 7263 7264 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7265 if (mat->cmap->mapping) { 7266 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7267 } 7268 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7269 mat->cmap = nmap; 7270 mat->cmap->mapping = l2g; 7271 } 7272 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7273 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7274 PetscFunctionReturn(0); 7275 } 7276 7277 /*@ 7278 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7279 7280 Logically Collective on Mat 7281 7282 Input Parameters: 7283 + mat - the matrix 7284 . fromRow - matrix from which to copy row block size 7285 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7286 7287 Level: developer 7288 7289 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7290 @*/ 7291 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7292 { 7293 PetscErrorCode ierr; 7294 7295 PetscFunctionBegin; 7296 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7297 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7298 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7299 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7300 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7301 PetscFunctionReturn(0); 7302 } 7303 7304 /*@ 7305 MatResidual - Default routine to calculate the residual. 7306 7307 Collective on Mat 7308 7309 Input Parameters: 7310 + mat - the matrix 7311 . b - the right-hand-side 7312 - x - the approximate solution 7313 7314 Output Parameter: 7315 . r - location to store the residual 7316 7317 Level: developer 7318 7319 .seealso: PCMGSetResidual() 7320 @*/ 7321 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7322 { 7323 PetscErrorCode ierr; 7324 7325 PetscFunctionBegin; 7326 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7327 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7328 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7329 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7330 PetscValidType(mat,1); 7331 MatCheckPreallocated(mat,1); 7332 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7333 if (!mat->ops->residual) { 7334 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7335 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7336 } else { 7337 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7338 } 7339 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7340 PetscFunctionReturn(0); 7341 } 7342 7343 /*@C 7344 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7345 7346 Collective on Mat 7347 7348 Input Parameters: 7349 + mat - the matrix 7350 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7351 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7352 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7353 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7354 always used. 7355 7356 Output Parameters: 7357 + n - number of rows in the (possibly compressed) matrix 7358 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7359 . ja - the column indices 7360 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7361 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7362 7363 Level: developer 7364 7365 Notes: 7366 You CANNOT change any of the ia[] or ja[] values. 7367 7368 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7369 7370 Fortran Notes: 7371 In Fortran use 7372 $ 7373 $ PetscInt ia(1), ja(1) 7374 $ PetscOffset iia, jja 7375 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7376 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7377 7378 or 7379 $ 7380 $ PetscInt, pointer :: ia(:),ja(:) 7381 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7382 $ ! Access the ith and jth entries via ia(i) and ja(j) 7383 7384 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7385 @*/ 7386 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7387 { 7388 PetscErrorCode ierr; 7389 7390 PetscFunctionBegin; 7391 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7392 PetscValidType(mat,1); 7393 PetscValidIntPointer(n,5); 7394 if (ia) PetscValidIntPointer(ia,6); 7395 if (ja) PetscValidIntPointer(ja,7); 7396 PetscValidIntPointer(done,8); 7397 MatCheckPreallocated(mat,1); 7398 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7399 else { 7400 *done = PETSC_TRUE; 7401 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7402 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7403 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7404 } 7405 PetscFunctionReturn(0); 7406 } 7407 7408 /*@C 7409 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7410 7411 Collective on Mat 7412 7413 Input Parameters: 7414 + mat - the matrix 7415 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7416 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7417 symmetrized 7418 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7419 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7420 always used. 7421 . n - number of columns in the (possibly compressed) matrix 7422 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7423 - ja - the row indices 7424 7425 Output Parameters: 7426 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7427 7428 Level: developer 7429 7430 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7431 @*/ 7432 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7433 { 7434 PetscErrorCode ierr; 7435 7436 PetscFunctionBegin; 7437 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7438 PetscValidType(mat,1); 7439 PetscValidIntPointer(n,4); 7440 if (ia) PetscValidIntPointer(ia,5); 7441 if (ja) PetscValidIntPointer(ja,6); 7442 PetscValidIntPointer(done,7); 7443 MatCheckPreallocated(mat,1); 7444 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7445 else { 7446 *done = PETSC_TRUE; 7447 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7448 } 7449 PetscFunctionReturn(0); 7450 } 7451 7452 /*@C 7453 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7454 MatGetRowIJ(). 7455 7456 Collective on Mat 7457 7458 Input Parameters: 7459 + mat - the matrix 7460 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7461 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7462 symmetrized 7463 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7464 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7465 always used. 7466 . n - size of (possibly compressed) matrix 7467 . ia - the row pointers 7468 - ja - the column indices 7469 7470 Output Parameters: 7471 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7472 7473 Note: 7474 This routine zeros out n, ia, and ja. This is to prevent accidental 7475 us of the array after it has been restored. If you pass NULL, it will 7476 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7477 7478 Level: developer 7479 7480 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7481 @*/ 7482 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7483 { 7484 PetscErrorCode ierr; 7485 7486 PetscFunctionBegin; 7487 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7488 PetscValidType(mat,1); 7489 if (ia) PetscValidIntPointer(ia,6); 7490 if (ja) PetscValidIntPointer(ja,7); 7491 PetscValidIntPointer(done,8); 7492 MatCheckPreallocated(mat,1); 7493 7494 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7495 else { 7496 *done = PETSC_TRUE; 7497 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7498 if (n) *n = 0; 7499 if (ia) *ia = NULL; 7500 if (ja) *ja = NULL; 7501 } 7502 PetscFunctionReturn(0); 7503 } 7504 7505 /*@C 7506 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7507 MatGetColumnIJ(). 7508 7509 Collective on Mat 7510 7511 Input Parameters: 7512 + mat - the matrix 7513 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7514 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7515 symmetrized 7516 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7517 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7518 always used. 7519 7520 Output Parameters: 7521 + n - size of (possibly compressed) matrix 7522 . ia - the column pointers 7523 . ja - the row indices 7524 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7525 7526 Level: developer 7527 7528 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7529 @*/ 7530 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7531 { 7532 PetscErrorCode ierr; 7533 7534 PetscFunctionBegin; 7535 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7536 PetscValidType(mat,1); 7537 if (ia) PetscValidIntPointer(ia,5); 7538 if (ja) PetscValidIntPointer(ja,6); 7539 PetscValidIntPointer(done,7); 7540 MatCheckPreallocated(mat,1); 7541 7542 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7543 else { 7544 *done = PETSC_TRUE; 7545 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7546 if (n) *n = 0; 7547 if (ia) *ia = NULL; 7548 if (ja) *ja = NULL; 7549 } 7550 PetscFunctionReturn(0); 7551 } 7552 7553 /*@C 7554 MatColoringPatch -Used inside matrix coloring routines that 7555 use MatGetRowIJ() and/or MatGetColumnIJ(). 7556 7557 Collective on Mat 7558 7559 Input Parameters: 7560 + mat - the matrix 7561 . ncolors - max color value 7562 . n - number of entries in colorarray 7563 - colorarray - array indicating color for each column 7564 7565 Output Parameters: 7566 . iscoloring - coloring generated using colorarray information 7567 7568 Level: developer 7569 7570 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7571 7572 @*/ 7573 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7574 { 7575 PetscErrorCode ierr; 7576 7577 PetscFunctionBegin; 7578 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7579 PetscValidType(mat,1); 7580 PetscValidIntPointer(colorarray,4); 7581 PetscValidPointer(iscoloring,5); 7582 MatCheckPreallocated(mat,1); 7583 7584 if (!mat->ops->coloringpatch) { 7585 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7586 } else { 7587 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7588 } 7589 PetscFunctionReturn(0); 7590 } 7591 7592 7593 /*@ 7594 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7595 7596 Logically Collective on Mat 7597 7598 Input Parameter: 7599 . mat - the factored matrix to be reset 7600 7601 Notes: 7602 This routine should be used only with factored matrices formed by in-place 7603 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7604 format). This option can save memory, for example, when solving nonlinear 7605 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7606 ILU(0) preconditioner. 7607 7608 Note that one can specify in-place ILU(0) factorization by calling 7609 .vb 7610 PCType(pc,PCILU); 7611 PCFactorSeUseInPlace(pc); 7612 .ve 7613 or by using the options -pc_type ilu -pc_factor_in_place 7614 7615 In-place factorization ILU(0) can also be used as a local 7616 solver for the blocks within the block Jacobi or additive Schwarz 7617 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7618 for details on setting local solver options. 7619 7620 Most users should employ the simplified KSP interface for linear solvers 7621 instead of working directly with matrix algebra routines such as this. 7622 See, e.g., KSPCreate(). 7623 7624 Level: developer 7625 7626 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7627 7628 @*/ 7629 PetscErrorCode MatSetUnfactored(Mat mat) 7630 { 7631 PetscErrorCode ierr; 7632 7633 PetscFunctionBegin; 7634 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7635 PetscValidType(mat,1); 7636 MatCheckPreallocated(mat,1); 7637 mat->factortype = MAT_FACTOR_NONE; 7638 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7639 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7640 PetscFunctionReturn(0); 7641 } 7642 7643 /*MC 7644 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7645 7646 Synopsis: 7647 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7648 7649 Not collective 7650 7651 Input Parameter: 7652 . x - matrix 7653 7654 Output Parameters: 7655 + xx_v - the Fortran90 pointer to the array 7656 - ierr - error code 7657 7658 Example of Usage: 7659 .vb 7660 PetscScalar, pointer xx_v(:,:) 7661 .... 7662 call MatDenseGetArrayF90(x,xx_v,ierr) 7663 a = xx_v(3) 7664 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7665 .ve 7666 7667 Level: advanced 7668 7669 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7670 7671 M*/ 7672 7673 /*MC 7674 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7675 accessed with MatDenseGetArrayF90(). 7676 7677 Synopsis: 7678 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7679 7680 Not collective 7681 7682 Input Parameters: 7683 + x - matrix 7684 - xx_v - the Fortran90 pointer to the array 7685 7686 Output Parameter: 7687 . ierr - error code 7688 7689 Example of Usage: 7690 .vb 7691 PetscScalar, pointer xx_v(:,:) 7692 .... 7693 call MatDenseGetArrayF90(x,xx_v,ierr) 7694 a = xx_v(3) 7695 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7696 .ve 7697 7698 Level: advanced 7699 7700 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7701 7702 M*/ 7703 7704 7705 /*MC 7706 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7707 7708 Synopsis: 7709 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7710 7711 Not collective 7712 7713 Input Parameter: 7714 . x - matrix 7715 7716 Output Parameters: 7717 + xx_v - the Fortran90 pointer to the array 7718 - ierr - error code 7719 7720 Example of Usage: 7721 .vb 7722 PetscScalar, pointer xx_v(:) 7723 .... 7724 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7725 a = xx_v(3) 7726 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7727 .ve 7728 7729 Level: advanced 7730 7731 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7732 7733 M*/ 7734 7735 /*MC 7736 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7737 accessed with MatSeqAIJGetArrayF90(). 7738 7739 Synopsis: 7740 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7741 7742 Not collective 7743 7744 Input Parameters: 7745 + x - matrix 7746 - xx_v - the Fortran90 pointer to the array 7747 7748 Output Parameter: 7749 . ierr - error code 7750 7751 Example of Usage: 7752 .vb 7753 PetscScalar, pointer xx_v(:) 7754 .... 7755 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7756 a = xx_v(3) 7757 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7758 .ve 7759 7760 Level: advanced 7761 7762 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7763 7764 M*/ 7765 7766 7767 /*@ 7768 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7769 as the original matrix. 7770 7771 Collective on Mat 7772 7773 Input Parameters: 7774 + mat - the original matrix 7775 . isrow - parallel IS containing the rows this processor should obtain 7776 . 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. 7777 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7778 7779 Output Parameter: 7780 . newmat - the new submatrix, of the same type as the old 7781 7782 Level: advanced 7783 7784 Notes: 7785 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7786 7787 Some matrix types place restrictions on the row and column indices, such 7788 as that they be sorted or that they be equal to each other. 7789 7790 The index sets may not have duplicate entries. 7791 7792 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7793 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7794 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7795 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7796 you are finished using it. 7797 7798 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7799 the input matrix. 7800 7801 If iscol is NULL then all columns are obtained (not supported in Fortran). 7802 7803 Example usage: 7804 Consider the following 8x8 matrix with 34 non-zero values, that is 7805 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7806 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7807 as follows: 7808 7809 .vb 7810 1 2 0 | 0 3 0 | 0 4 7811 Proc0 0 5 6 | 7 0 0 | 8 0 7812 9 0 10 | 11 0 0 | 12 0 7813 ------------------------------------- 7814 13 0 14 | 15 16 17 | 0 0 7815 Proc1 0 18 0 | 19 20 21 | 0 0 7816 0 0 0 | 22 23 0 | 24 0 7817 ------------------------------------- 7818 Proc2 25 26 27 | 0 0 28 | 29 0 7819 30 0 0 | 31 32 33 | 0 34 7820 .ve 7821 7822 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7823 7824 .vb 7825 2 0 | 0 3 0 | 0 7826 Proc0 5 6 | 7 0 0 | 8 7827 ------------------------------- 7828 Proc1 18 0 | 19 20 21 | 0 7829 ------------------------------- 7830 Proc2 26 27 | 0 0 28 | 29 7831 0 0 | 31 32 33 | 0 7832 .ve 7833 7834 7835 .seealso: MatCreateSubMatrices() 7836 @*/ 7837 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7838 { 7839 PetscErrorCode ierr; 7840 PetscMPIInt size; 7841 Mat *local; 7842 IS iscoltmp; 7843 7844 PetscFunctionBegin; 7845 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7846 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7847 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7848 PetscValidPointer(newmat,5); 7849 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7850 PetscValidType(mat,1); 7851 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7852 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7853 7854 MatCheckPreallocated(mat,1); 7855 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7856 7857 if (!iscol || isrow == iscol) { 7858 PetscBool stride; 7859 PetscMPIInt grabentirematrix = 0,grab; 7860 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7861 if (stride) { 7862 PetscInt first,step,n,rstart,rend; 7863 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7864 if (step == 1) { 7865 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7866 if (rstart == first) { 7867 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7868 if (n == rend-rstart) { 7869 grabentirematrix = 1; 7870 } 7871 } 7872 } 7873 } 7874 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7875 if (grab) { 7876 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7877 if (cll == MAT_INITIAL_MATRIX) { 7878 *newmat = mat; 7879 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7880 } 7881 PetscFunctionReturn(0); 7882 } 7883 } 7884 7885 if (!iscol) { 7886 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7887 } else { 7888 iscoltmp = iscol; 7889 } 7890 7891 /* if original matrix is on just one processor then use submatrix generated */ 7892 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7893 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7894 goto setproperties; 7895 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 7896 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7897 *newmat = *local; 7898 ierr = PetscFree(local);CHKERRQ(ierr); 7899 goto setproperties; 7900 } else if (!mat->ops->createsubmatrix) { 7901 /* Create a new matrix type that implements the operation using the full matrix */ 7902 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7903 switch (cll) { 7904 case MAT_INITIAL_MATRIX: 7905 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7906 break; 7907 case MAT_REUSE_MATRIX: 7908 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7909 break; 7910 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7911 } 7912 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7913 goto setproperties; 7914 } 7915 7916 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7917 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7918 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7919 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7920 7921 /* Propagate symmetry information for diagonal blocks */ 7922 setproperties: 7923 if (isrow == iscoltmp) { 7924 if (mat->symmetric_set && mat->symmetric) { 7925 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7926 } 7927 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 7928 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7929 } 7930 if (mat->hermitian_set && mat->hermitian) { 7931 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 7932 } 7933 if (mat->spd_set && mat->spd) { 7934 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 7935 } 7936 } 7937 7938 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7939 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7940 PetscFunctionReturn(0); 7941 } 7942 7943 /*@ 7944 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7945 used during the assembly process to store values that belong to 7946 other processors. 7947 7948 Not Collective 7949 7950 Input Parameters: 7951 + mat - the matrix 7952 . size - the initial size of the stash. 7953 - bsize - the initial size of the block-stash(if used). 7954 7955 Options Database Keys: 7956 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7957 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7958 7959 Level: intermediate 7960 7961 Notes: 7962 The block-stash is used for values set with MatSetValuesBlocked() while 7963 the stash is used for values set with MatSetValues() 7964 7965 Run with the option -info and look for output of the form 7966 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7967 to determine the appropriate value, MM, to use for size and 7968 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7969 to determine the value, BMM to use for bsize 7970 7971 7972 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7973 7974 @*/ 7975 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7976 { 7977 PetscErrorCode ierr; 7978 7979 PetscFunctionBegin; 7980 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7981 PetscValidType(mat,1); 7982 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7983 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7984 PetscFunctionReturn(0); 7985 } 7986 7987 /*@ 7988 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7989 the matrix 7990 7991 Neighbor-wise Collective on Mat 7992 7993 Input Parameters: 7994 + mat - the matrix 7995 . x,y - the vectors 7996 - w - where the result is stored 7997 7998 Level: intermediate 7999 8000 Notes: 8001 w may be the same vector as y. 8002 8003 This allows one to use either the restriction or interpolation (its transpose) 8004 matrix to do the interpolation 8005 8006 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8007 8008 @*/ 8009 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8010 { 8011 PetscErrorCode ierr; 8012 PetscInt M,N,Ny; 8013 8014 PetscFunctionBegin; 8015 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8016 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8017 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8018 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8019 PetscValidType(A,1); 8020 MatCheckPreallocated(A,1); 8021 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8022 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8023 if (M == Ny) { 8024 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8025 } else { 8026 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8027 } 8028 PetscFunctionReturn(0); 8029 } 8030 8031 /*@ 8032 MatInterpolate - y = A*x or A'*x depending on the shape of 8033 the matrix 8034 8035 Neighbor-wise Collective on Mat 8036 8037 Input Parameters: 8038 + mat - the matrix 8039 - x,y - the vectors 8040 8041 Level: intermediate 8042 8043 Notes: 8044 This allows one to use either the restriction or interpolation (its transpose) 8045 matrix to do the interpolation 8046 8047 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8048 8049 @*/ 8050 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8051 { 8052 PetscErrorCode ierr; 8053 PetscInt M,N,Ny; 8054 8055 PetscFunctionBegin; 8056 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8057 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8058 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8059 PetscValidType(A,1); 8060 MatCheckPreallocated(A,1); 8061 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8062 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8063 if (M == Ny) { 8064 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8065 } else { 8066 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8067 } 8068 PetscFunctionReturn(0); 8069 } 8070 8071 /*@ 8072 MatRestrict - y = A*x or A'*x 8073 8074 Neighbor-wise Collective on Mat 8075 8076 Input Parameters: 8077 + mat - the matrix 8078 - x,y - the vectors 8079 8080 Level: intermediate 8081 8082 Notes: 8083 This allows one to use either the restriction or interpolation (its transpose) 8084 matrix to do the restriction 8085 8086 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8087 8088 @*/ 8089 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8090 { 8091 PetscErrorCode ierr; 8092 PetscInt M,N,Ny; 8093 8094 PetscFunctionBegin; 8095 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8096 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8097 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8098 PetscValidType(A,1); 8099 MatCheckPreallocated(A,1); 8100 8101 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8102 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8103 if (M == Ny) { 8104 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8105 } else { 8106 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8107 } 8108 PetscFunctionReturn(0); 8109 } 8110 8111 /*@ 8112 MatGetNullSpace - retrieves the null space of a matrix. 8113 8114 Logically Collective on Mat 8115 8116 Input Parameters: 8117 + mat - the matrix 8118 - nullsp - the null space object 8119 8120 Level: developer 8121 8122 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8123 @*/ 8124 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8125 { 8126 PetscFunctionBegin; 8127 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8128 PetscValidPointer(nullsp,2); 8129 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8130 PetscFunctionReturn(0); 8131 } 8132 8133 /*@ 8134 MatSetNullSpace - attaches a null space to a matrix. 8135 8136 Logically Collective on Mat 8137 8138 Input Parameters: 8139 + mat - the matrix 8140 - nullsp - the null space object 8141 8142 Level: advanced 8143 8144 Notes: 8145 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8146 8147 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8148 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8149 8150 You can remove the null space by calling this routine with an nullsp of NULL 8151 8152 8153 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8154 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). 8155 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 8156 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 8157 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). 8158 8159 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8160 8161 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 8162 routine also automatically calls MatSetTransposeNullSpace(). 8163 8164 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8165 @*/ 8166 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8167 { 8168 PetscErrorCode ierr; 8169 8170 PetscFunctionBegin; 8171 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8172 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8173 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8174 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8175 mat->nullsp = nullsp; 8176 if (mat->symmetric_set && mat->symmetric) { 8177 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8178 } 8179 PetscFunctionReturn(0); 8180 } 8181 8182 /*@ 8183 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8184 8185 Logically Collective on Mat 8186 8187 Input Parameters: 8188 + mat - the matrix 8189 - nullsp - the null space object 8190 8191 Level: developer 8192 8193 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8194 @*/ 8195 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8196 { 8197 PetscFunctionBegin; 8198 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8199 PetscValidType(mat,1); 8200 PetscValidPointer(nullsp,2); 8201 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8202 PetscFunctionReturn(0); 8203 } 8204 8205 /*@ 8206 MatSetTransposeNullSpace - attaches a null space to a matrix. 8207 8208 Logically Collective on Mat 8209 8210 Input Parameters: 8211 + mat - the matrix 8212 - nullsp - the null space object 8213 8214 Level: advanced 8215 8216 Notes: 8217 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. 8218 You must also call MatSetNullSpace() 8219 8220 8221 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8222 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). 8223 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 8224 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 8225 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). 8226 8227 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8228 8229 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8230 @*/ 8231 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8232 { 8233 PetscErrorCode ierr; 8234 8235 PetscFunctionBegin; 8236 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8237 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8238 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8239 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8240 mat->transnullsp = nullsp; 8241 PetscFunctionReturn(0); 8242 } 8243 8244 /*@ 8245 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8246 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8247 8248 Logically Collective on Mat 8249 8250 Input Parameters: 8251 + mat - the matrix 8252 - nullsp - the null space object 8253 8254 Level: advanced 8255 8256 Notes: 8257 Overwrites any previous near null space that may have been attached 8258 8259 You can remove the null space by calling this routine with an nullsp of NULL 8260 8261 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8262 @*/ 8263 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8264 { 8265 PetscErrorCode ierr; 8266 8267 PetscFunctionBegin; 8268 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8269 PetscValidType(mat,1); 8270 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8271 MatCheckPreallocated(mat,1); 8272 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8273 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8274 mat->nearnullsp = nullsp; 8275 PetscFunctionReturn(0); 8276 } 8277 8278 /*@ 8279 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8280 8281 Not Collective 8282 8283 Input Parameters: 8284 . mat - the matrix 8285 8286 Output Parameters: 8287 . nullsp - the null space object, NULL if not set 8288 8289 Level: developer 8290 8291 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8292 @*/ 8293 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8294 { 8295 PetscFunctionBegin; 8296 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8297 PetscValidType(mat,1); 8298 PetscValidPointer(nullsp,2); 8299 MatCheckPreallocated(mat,1); 8300 *nullsp = mat->nearnullsp; 8301 PetscFunctionReturn(0); 8302 } 8303 8304 /*@C 8305 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8306 8307 Collective on Mat 8308 8309 Input Parameters: 8310 + mat - the matrix 8311 . row - row/column permutation 8312 . fill - expected fill factor >= 1.0 8313 - level - level of fill, for ICC(k) 8314 8315 Notes: 8316 Probably really in-place only when level of fill is zero, otherwise allocates 8317 new space to store factored matrix and deletes previous memory. 8318 8319 Most users should employ the simplified KSP interface for linear solvers 8320 instead of working directly with matrix algebra routines such as this. 8321 See, e.g., KSPCreate(). 8322 8323 Level: developer 8324 8325 8326 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8327 8328 Developer Note: fortran interface is not autogenerated as the f90 8329 interface defintion cannot be generated correctly [due to MatFactorInfo] 8330 8331 @*/ 8332 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8333 { 8334 PetscErrorCode ierr; 8335 8336 PetscFunctionBegin; 8337 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8338 PetscValidType(mat,1); 8339 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8340 PetscValidPointer(info,3); 8341 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8342 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8343 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8344 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8345 MatCheckPreallocated(mat,1); 8346 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8347 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8348 PetscFunctionReturn(0); 8349 } 8350 8351 /*@ 8352 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8353 ghosted ones. 8354 8355 Not Collective 8356 8357 Input Parameters: 8358 + mat - the matrix 8359 - diag = the diagonal values, including ghost ones 8360 8361 Level: developer 8362 8363 Notes: 8364 Works only for MPIAIJ and MPIBAIJ matrices 8365 8366 .seealso: MatDiagonalScale() 8367 @*/ 8368 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8369 { 8370 PetscErrorCode ierr; 8371 PetscMPIInt size; 8372 8373 PetscFunctionBegin; 8374 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8375 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8376 PetscValidType(mat,1); 8377 8378 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8379 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8380 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8381 if (size == 1) { 8382 PetscInt n,m; 8383 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8384 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8385 if (m == n) { 8386 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8387 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8388 } else { 8389 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8390 } 8391 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8392 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8393 PetscFunctionReturn(0); 8394 } 8395 8396 /*@ 8397 MatGetInertia - Gets the inertia from a factored matrix 8398 8399 Collective on Mat 8400 8401 Input Parameter: 8402 . mat - the matrix 8403 8404 Output Parameters: 8405 + nneg - number of negative eigenvalues 8406 . nzero - number of zero eigenvalues 8407 - npos - number of positive eigenvalues 8408 8409 Level: advanced 8410 8411 Notes: 8412 Matrix must have been factored by MatCholeskyFactor() 8413 8414 8415 @*/ 8416 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8417 { 8418 PetscErrorCode ierr; 8419 8420 PetscFunctionBegin; 8421 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8422 PetscValidType(mat,1); 8423 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8424 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8425 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8426 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8427 PetscFunctionReturn(0); 8428 } 8429 8430 /* ----------------------------------------------------------------*/ 8431 /*@C 8432 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8433 8434 Neighbor-wise Collective on Mats 8435 8436 Input Parameters: 8437 + mat - the factored matrix 8438 - b - the right-hand-side vectors 8439 8440 Output Parameter: 8441 . x - the result vectors 8442 8443 Notes: 8444 The vectors b and x cannot be the same. I.e., one cannot 8445 call MatSolves(A,x,x). 8446 8447 Notes: 8448 Most users should employ the simplified KSP interface for linear solvers 8449 instead of working directly with matrix algebra routines such as this. 8450 See, e.g., KSPCreate(). 8451 8452 Level: developer 8453 8454 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8455 @*/ 8456 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8457 { 8458 PetscErrorCode ierr; 8459 8460 PetscFunctionBegin; 8461 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8462 PetscValidType(mat,1); 8463 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8464 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8465 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8466 8467 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8468 MatCheckPreallocated(mat,1); 8469 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8470 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8471 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8472 PetscFunctionReturn(0); 8473 } 8474 8475 /*@ 8476 MatIsSymmetric - Test whether a matrix is symmetric 8477 8478 Collective on Mat 8479 8480 Input Parameter: 8481 + A - the matrix to test 8482 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8483 8484 Output Parameters: 8485 . flg - the result 8486 8487 Notes: 8488 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8489 8490 Level: intermediate 8491 8492 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8493 @*/ 8494 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8495 { 8496 PetscErrorCode ierr; 8497 8498 PetscFunctionBegin; 8499 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8500 PetscValidBoolPointer(flg,2); 8501 8502 if (!A->symmetric_set) { 8503 if (!A->ops->issymmetric) { 8504 MatType mattype; 8505 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8506 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8507 } 8508 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8509 if (!tol) { 8510 A->symmetric_set = PETSC_TRUE; 8511 A->symmetric = *flg; 8512 if (A->symmetric) { 8513 A->structurally_symmetric_set = PETSC_TRUE; 8514 A->structurally_symmetric = PETSC_TRUE; 8515 } 8516 } 8517 } else if (A->symmetric) { 8518 *flg = PETSC_TRUE; 8519 } else if (!tol) { 8520 *flg = PETSC_FALSE; 8521 } else { 8522 if (!A->ops->issymmetric) { 8523 MatType mattype; 8524 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8525 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8526 } 8527 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8528 } 8529 PetscFunctionReturn(0); 8530 } 8531 8532 /*@ 8533 MatIsHermitian - Test whether a matrix is Hermitian 8534 8535 Collective on Mat 8536 8537 Input Parameter: 8538 + A - the matrix to test 8539 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8540 8541 Output Parameters: 8542 . flg - the result 8543 8544 Level: intermediate 8545 8546 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8547 MatIsSymmetricKnown(), MatIsSymmetric() 8548 @*/ 8549 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8550 { 8551 PetscErrorCode ierr; 8552 8553 PetscFunctionBegin; 8554 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8555 PetscValidBoolPointer(flg,2); 8556 8557 if (!A->hermitian_set) { 8558 if (!A->ops->ishermitian) { 8559 MatType mattype; 8560 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8561 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8562 } 8563 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8564 if (!tol) { 8565 A->hermitian_set = PETSC_TRUE; 8566 A->hermitian = *flg; 8567 if (A->hermitian) { 8568 A->structurally_symmetric_set = PETSC_TRUE; 8569 A->structurally_symmetric = PETSC_TRUE; 8570 } 8571 } 8572 } else if (A->hermitian) { 8573 *flg = PETSC_TRUE; 8574 } else if (!tol) { 8575 *flg = PETSC_FALSE; 8576 } else { 8577 if (!A->ops->ishermitian) { 8578 MatType mattype; 8579 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8580 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8581 } 8582 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8583 } 8584 PetscFunctionReturn(0); 8585 } 8586 8587 /*@ 8588 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8589 8590 Not Collective 8591 8592 Input Parameter: 8593 . A - the matrix to check 8594 8595 Output Parameters: 8596 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8597 - flg - the result 8598 8599 Level: advanced 8600 8601 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8602 if you want it explicitly checked 8603 8604 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8605 @*/ 8606 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8607 { 8608 PetscFunctionBegin; 8609 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8610 PetscValidPointer(set,2); 8611 PetscValidBoolPointer(flg,3); 8612 if (A->symmetric_set) { 8613 *set = PETSC_TRUE; 8614 *flg = A->symmetric; 8615 } else { 8616 *set = PETSC_FALSE; 8617 } 8618 PetscFunctionReturn(0); 8619 } 8620 8621 /*@ 8622 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8623 8624 Not Collective 8625 8626 Input Parameter: 8627 . A - the matrix to check 8628 8629 Output Parameters: 8630 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8631 - flg - the result 8632 8633 Level: advanced 8634 8635 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8636 if you want it explicitly checked 8637 8638 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8639 @*/ 8640 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8641 { 8642 PetscFunctionBegin; 8643 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8644 PetscValidPointer(set,2); 8645 PetscValidBoolPointer(flg,3); 8646 if (A->hermitian_set) { 8647 *set = PETSC_TRUE; 8648 *flg = A->hermitian; 8649 } else { 8650 *set = PETSC_FALSE; 8651 } 8652 PetscFunctionReturn(0); 8653 } 8654 8655 /*@ 8656 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8657 8658 Collective on Mat 8659 8660 Input Parameter: 8661 . A - the matrix to test 8662 8663 Output Parameters: 8664 . flg - the result 8665 8666 Level: intermediate 8667 8668 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8669 @*/ 8670 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8671 { 8672 PetscErrorCode ierr; 8673 8674 PetscFunctionBegin; 8675 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8676 PetscValidBoolPointer(flg,2); 8677 if (!A->structurally_symmetric_set) { 8678 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8679 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8680 8681 A->structurally_symmetric_set = PETSC_TRUE; 8682 } 8683 *flg = A->structurally_symmetric; 8684 PetscFunctionReturn(0); 8685 } 8686 8687 /*@ 8688 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8689 to be communicated to other processors during the MatAssemblyBegin/End() process 8690 8691 Not collective 8692 8693 Input Parameter: 8694 . vec - the vector 8695 8696 Output Parameters: 8697 + nstash - the size of the stash 8698 . reallocs - the number of additional mallocs incurred. 8699 . bnstash - the size of the block stash 8700 - breallocs - the number of additional mallocs incurred.in the block stash 8701 8702 Level: advanced 8703 8704 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8705 8706 @*/ 8707 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8708 { 8709 PetscErrorCode ierr; 8710 8711 PetscFunctionBegin; 8712 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8713 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8714 PetscFunctionReturn(0); 8715 } 8716 8717 /*@C 8718 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8719 parallel layout 8720 8721 Collective on Mat 8722 8723 Input Parameter: 8724 . mat - the matrix 8725 8726 Output Parameter: 8727 + right - (optional) vector that the matrix can be multiplied against 8728 - left - (optional) vector that the matrix vector product can be stored in 8729 8730 Notes: 8731 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(). 8732 8733 Notes: 8734 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8735 8736 Level: advanced 8737 8738 .seealso: MatCreate(), VecDestroy() 8739 @*/ 8740 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8741 { 8742 PetscErrorCode ierr; 8743 8744 PetscFunctionBegin; 8745 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8746 PetscValidType(mat,1); 8747 if (mat->ops->getvecs) { 8748 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8749 } else { 8750 PetscInt rbs,cbs; 8751 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8752 if (right) { 8753 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8754 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8755 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8756 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8757 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8758 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8759 } 8760 if (left) { 8761 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8762 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8763 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8764 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8765 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8766 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8767 } 8768 } 8769 PetscFunctionReturn(0); 8770 } 8771 8772 /*@C 8773 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8774 with default values. 8775 8776 Not Collective 8777 8778 Input Parameters: 8779 . info - the MatFactorInfo data structure 8780 8781 8782 Notes: 8783 The solvers are generally used through the KSP and PC objects, for example 8784 PCLU, PCILU, PCCHOLESKY, PCICC 8785 8786 Level: developer 8787 8788 .seealso: MatFactorInfo 8789 8790 Developer Note: fortran interface is not autogenerated as the f90 8791 interface defintion cannot be generated correctly [due to MatFactorInfo] 8792 8793 @*/ 8794 8795 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8796 { 8797 PetscErrorCode ierr; 8798 8799 PetscFunctionBegin; 8800 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8801 PetscFunctionReturn(0); 8802 } 8803 8804 /*@ 8805 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8806 8807 Collective on Mat 8808 8809 Input Parameters: 8810 + mat - the factored matrix 8811 - is - the index set defining the Schur indices (0-based) 8812 8813 Notes: 8814 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8815 8816 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8817 8818 Level: developer 8819 8820 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8821 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8822 8823 @*/ 8824 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8825 { 8826 PetscErrorCode ierr,(*f)(Mat,IS); 8827 8828 PetscFunctionBegin; 8829 PetscValidType(mat,1); 8830 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8831 PetscValidType(is,2); 8832 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8833 PetscCheckSameComm(mat,1,is,2); 8834 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8835 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8836 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"); 8837 if (mat->schur) { 8838 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8839 } 8840 ierr = (*f)(mat,is);CHKERRQ(ierr); 8841 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8842 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 8843 PetscFunctionReturn(0); 8844 } 8845 8846 /*@ 8847 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8848 8849 Logically Collective on Mat 8850 8851 Input Parameters: 8852 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8853 . S - location where to return the Schur complement, can be NULL 8854 - status - the status of the Schur complement matrix, can be NULL 8855 8856 Notes: 8857 You must call MatFactorSetSchurIS() before calling this routine. 8858 8859 The routine provides a copy of the Schur matrix stored within the solver data structures. 8860 The caller must destroy the object when it is no longer needed. 8861 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 8862 8863 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) 8864 8865 Developer Notes: 8866 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 8867 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 8868 8869 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8870 8871 Level: advanced 8872 8873 References: 8874 8875 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 8876 @*/ 8877 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8878 { 8879 PetscErrorCode ierr; 8880 8881 PetscFunctionBegin; 8882 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8883 if (S) PetscValidPointer(S,2); 8884 if (status) PetscValidPointer(status,3); 8885 if (S) { 8886 PetscErrorCode (*f)(Mat,Mat*); 8887 8888 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 8889 if (f) { 8890 ierr = (*f)(F,S);CHKERRQ(ierr); 8891 } else { 8892 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 8893 } 8894 } 8895 if (status) *status = F->schur_status; 8896 PetscFunctionReturn(0); 8897 } 8898 8899 /*@ 8900 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 8901 8902 Logically Collective on Mat 8903 8904 Input Parameters: 8905 + F - the factored matrix obtained by calling MatGetFactor() 8906 . *S - location where to return the Schur complement, can be NULL 8907 - status - the status of the Schur complement matrix, can be NULL 8908 8909 Notes: 8910 You must call MatFactorSetSchurIS() before calling this routine. 8911 8912 Schur complement mode is currently implemented for sequential matrices. 8913 The routine returns a the Schur Complement stored within the data strutures of the solver. 8914 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 8915 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 8916 8917 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 8918 8919 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8920 8921 Level: advanced 8922 8923 References: 8924 8925 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8926 @*/ 8927 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8928 { 8929 PetscFunctionBegin; 8930 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8931 if (S) PetscValidPointer(S,2); 8932 if (status) PetscValidPointer(status,3); 8933 if (S) *S = F->schur; 8934 if (status) *status = F->schur_status; 8935 PetscFunctionReturn(0); 8936 } 8937 8938 /*@ 8939 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8940 8941 Logically Collective on Mat 8942 8943 Input Parameters: 8944 + F - the factored matrix obtained by calling MatGetFactor() 8945 . *S - location where the Schur complement is stored 8946 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 8947 8948 Notes: 8949 8950 Level: advanced 8951 8952 References: 8953 8954 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8955 @*/ 8956 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 8957 { 8958 PetscErrorCode ierr; 8959 8960 PetscFunctionBegin; 8961 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8962 if (S) { 8963 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 8964 *S = NULL; 8965 } 8966 F->schur_status = status; 8967 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 8968 PetscFunctionReturn(0); 8969 } 8970 8971 /*@ 8972 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 8973 8974 Logically Collective on Mat 8975 8976 Input Parameters: 8977 + F - the factored matrix obtained by calling MatGetFactor() 8978 . rhs - location where the right hand side of the Schur complement system is stored 8979 - sol - location where the solution of the Schur complement system has to be returned 8980 8981 Notes: 8982 The sizes of the vectors should match the size of the Schur complement 8983 8984 Must be called after MatFactorSetSchurIS() 8985 8986 Level: advanced 8987 8988 References: 8989 8990 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 8991 @*/ 8992 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 8993 { 8994 PetscErrorCode ierr; 8995 8996 PetscFunctionBegin; 8997 PetscValidType(F,1); 8998 PetscValidType(rhs,2); 8999 PetscValidType(sol,3); 9000 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9001 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9002 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9003 PetscCheckSameComm(F,1,rhs,2); 9004 PetscCheckSameComm(F,1,sol,3); 9005 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9006 switch (F->schur_status) { 9007 case MAT_FACTOR_SCHUR_FACTORED: 9008 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9009 break; 9010 case MAT_FACTOR_SCHUR_INVERTED: 9011 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9012 break; 9013 default: 9014 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9015 break; 9016 } 9017 PetscFunctionReturn(0); 9018 } 9019 9020 /*@ 9021 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9022 9023 Logically Collective on Mat 9024 9025 Input Parameters: 9026 + F - the factored matrix obtained by calling MatGetFactor() 9027 . rhs - location where the right hand side of the Schur complement system is stored 9028 - sol - location where the solution of the Schur complement system has to be returned 9029 9030 Notes: 9031 The sizes of the vectors should match the size of the Schur complement 9032 9033 Must be called after MatFactorSetSchurIS() 9034 9035 Level: advanced 9036 9037 References: 9038 9039 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9040 @*/ 9041 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9042 { 9043 PetscErrorCode ierr; 9044 9045 PetscFunctionBegin; 9046 PetscValidType(F,1); 9047 PetscValidType(rhs,2); 9048 PetscValidType(sol,3); 9049 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9050 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9051 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9052 PetscCheckSameComm(F,1,rhs,2); 9053 PetscCheckSameComm(F,1,sol,3); 9054 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9055 switch (F->schur_status) { 9056 case MAT_FACTOR_SCHUR_FACTORED: 9057 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9058 break; 9059 case MAT_FACTOR_SCHUR_INVERTED: 9060 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9061 break; 9062 default: 9063 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9064 break; 9065 } 9066 PetscFunctionReturn(0); 9067 } 9068 9069 /*@ 9070 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9071 9072 Logically Collective on Mat 9073 9074 Input Parameters: 9075 . F - the factored matrix obtained by calling MatGetFactor() 9076 9077 Notes: 9078 Must be called after MatFactorSetSchurIS(). 9079 9080 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9081 9082 Level: advanced 9083 9084 References: 9085 9086 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9087 @*/ 9088 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9089 { 9090 PetscErrorCode ierr; 9091 9092 PetscFunctionBegin; 9093 PetscValidType(F,1); 9094 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9095 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9096 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9097 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9098 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9099 PetscFunctionReturn(0); 9100 } 9101 9102 /*@ 9103 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9104 9105 Logically Collective on Mat 9106 9107 Input Parameters: 9108 . F - the factored matrix obtained by calling MatGetFactor() 9109 9110 Notes: 9111 Must be called after MatFactorSetSchurIS(). 9112 9113 Level: advanced 9114 9115 References: 9116 9117 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9118 @*/ 9119 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9120 { 9121 PetscErrorCode ierr; 9122 9123 PetscFunctionBegin; 9124 PetscValidType(F,1); 9125 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9126 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9127 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9128 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9129 PetscFunctionReturn(0); 9130 } 9131 9132 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9133 { 9134 Mat AP; 9135 PetscErrorCode ierr; 9136 9137 PetscFunctionBegin; 9138 ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr); 9139 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr); 9140 ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr); 9141 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9142 PetscFunctionReturn(0); 9143 } 9144 9145 /*@ 9146 MatPtAP - Creates the matrix product C = P^T * A * P 9147 9148 Neighbor-wise Collective on Mat 9149 9150 Input Parameters: 9151 + A - the matrix 9152 . P - the projection matrix 9153 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9154 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9155 if the result is a dense matrix this is irrelevent 9156 9157 Output Parameters: 9158 . C - the product matrix 9159 9160 Notes: 9161 C will be created and must be destroyed by the user with MatDestroy(). 9162 9163 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9164 9165 Level: intermediate 9166 9167 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9168 @*/ 9169 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9170 { 9171 PetscErrorCode ierr; 9172 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9173 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9174 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9175 PetscBool sametype; 9176 9177 PetscFunctionBegin; 9178 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9179 PetscValidType(A,1); 9180 MatCheckPreallocated(A,1); 9181 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9182 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9183 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9184 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9185 PetscValidType(P,2); 9186 MatCheckPreallocated(P,2); 9187 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9188 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9189 9190 if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N); 9191 if (P->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9192 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9193 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9194 9195 if (scall == MAT_REUSE_MATRIX) { 9196 PetscValidPointer(*C,5); 9197 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9198 9199 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9200 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9201 if ((*C)->ops->ptapnumeric) { 9202 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9203 } else { 9204 ierr = MatPtAP_Basic(A,P,scall,fill,C); 9205 } 9206 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9207 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9208 PetscFunctionReturn(0); 9209 } 9210 9211 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9212 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9213 9214 fA = A->ops->ptap; 9215 fP = P->ops->ptap; 9216 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9217 if (fP == fA && sametype) { 9218 ptap = fA; 9219 } else { 9220 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9221 char ptapname[256]; 9222 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9223 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9224 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9225 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9226 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9227 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9228 } 9229 9230 if (!ptap) ptap = MatPtAP_Basic; 9231 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9232 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9233 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9234 if (A->symmetric_set && A->symmetric) { 9235 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9236 } 9237 PetscFunctionReturn(0); 9238 } 9239 9240 /*@ 9241 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9242 9243 Neighbor-wise Collective on Mat 9244 9245 Input Parameters: 9246 + A - the matrix 9247 - P - the projection matrix 9248 9249 Output Parameters: 9250 . C - the product matrix 9251 9252 Notes: 9253 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9254 the user using MatDeatroy(). 9255 9256 This routine is currently only implemented for pairs of AIJ matrices and classes 9257 which inherit from AIJ. C will be of type MATAIJ. 9258 9259 Level: intermediate 9260 9261 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9262 @*/ 9263 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9264 { 9265 PetscErrorCode ierr; 9266 9267 PetscFunctionBegin; 9268 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9269 PetscValidType(A,1); 9270 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9271 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9272 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9273 PetscValidType(P,2); 9274 MatCheckPreallocated(P,2); 9275 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9276 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9277 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9278 PetscValidType(C,3); 9279 MatCheckPreallocated(C,3); 9280 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9281 if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N); 9282 if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9283 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9284 if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N); 9285 MatCheckPreallocated(A,1); 9286 9287 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9288 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9289 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9290 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9291 PetscFunctionReturn(0); 9292 } 9293 9294 /*@ 9295 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9296 9297 Neighbor-wise Collective on Mat 9298 9299 Input Parameters: 9300 + A - the matrix 9301 - P - the projection matrix 9302 9303 Output Parameters: 9304 . C - the (i,j) structure of the product matrix 9305 9306 Notes: 9307 C will be created and must be destroyed by the user with MatDestroy(). 9308 9309 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9310 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9311 this (i,j) structure by calling MatPtAPNumeric(). 9312 9313 Level: intermediate 9314 9315 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9316 @*/ 9317 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9318 { 9319 PetscErrorCode ierr; 9320 9321 PetscFunctionBegin; 9322 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9323 PetscValidType(A,1); 9324 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9325 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9326 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9327 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9328 PetscValidType(P,2); 9329 MatCheckPreallocated(P,2); 9330 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9331 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9332 PetscValidPointer(C,3); 9333 9334 if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9335 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9336 MatCheckPreallocated(A,1); 9337 9338 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9339 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9340 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9341 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9342 9343 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9344 PetscFunctionReturn(0); 9345 } 9346 9347 /*@ 9348 MatRARt - Creates the matrix product C = R * A * R^T 9349 9350 Neighbor-wise Collective on Mat 9351 9352 Input Parameters: 9353 + A - the matrix 9354 . R - the projection matrix 9355 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9356 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9357 if the result is a dense matrix this is irrelevent 9358 9359 Output Parameters: 9360 . C - the product matrix 9361 9362 Notes: 9363 C will be created and must be destroyed by the user with MatDestroy(). 9364 9365 This routine is currently only implemented for pairs of AIJ matrices and classes 9366 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9367 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9368 We recommend using MatPtAP(). 9369 9370 Level: intermediate 9371 9372 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9373 @*/ 9374 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9375 { 9376 PetscErrorCode ierr; 9377 9378 PetscFunctionBegin; 9379 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9380 PetscValidType(A,1); 9381 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9382 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9383 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9384 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9385 PetscValidType(R,2); 9386 MatCheckPreallocated(R,2); 9387 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9388 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9389 PetscValidPointer(C,3); 9390 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9391 9392 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9393 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9394 MatCheckPreallocated(A,1); 9395 9396 if (!A->ops->rart) { 9397 Mat Rt; 9398 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9399 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9400 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9401 PetscFunctionReturn(0); 9402 } 9403 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9404 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9405 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9406 PetscFunctionReturn(0); 9407 } 9408 9409 /*@ 9410 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9411 9412 Neighbor-wise Collective on Mat 9413 9414 Input Parameters: 9415 + A - the matrix 9416 - R - the projection matrix 9417 9418 Output Parameters: 9419 . C - the product matrix 9420 9421 Notes: 9422 C must have been created by calling MatRARtSymbolic and must be destroyed by 9423 the user using MatDestroy(). 9424 9425 This routine is currently only implemented for pairs of AIJ matrices and classes 9426 which inherit from AIJ. C will be of type MATAIJ. 9427 9428 Level: intermediate 9429 9430 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9431 @*/ 9432 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9433 { 9434 PetscErrorCode ierr; 9435 9436 PetscFunctionBegin; 9437 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9438 PetscValidType(A,1); 9439 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9440 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9441 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9442 PetscValidType(R,2); 9443 MatCheckPreallocated(R,2); 9444 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9445 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9446 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9447 PetscValidType(C,3); 9448 MatCheckPreallocated(C,3); 9449 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9450 if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N); 9451 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9452 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9453 if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N); 9454 MatCheckPreallocated(A,1); 9455 9456 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9457 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9458 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9459 PetscFunctionReturn(0); 9460 } 9461 9462 /*@ 9463 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9464 9465 Neighbor-wise Collective on Mat 9466 9467 Input Parameters: 9468 + A - the matrix 9469 - R - the projection matrix 9470 9471 Output Parameters: 9472 . C - the (i,j) structure of the product matrix 9473 9474 Notes: 9475 C will be created and must be destroyed by the user with MatDestroy(). 9476 9477 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9478 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9479 this (i,j) structure by calling MatRARtNumeric(). 9480 9481 Level: intermediate 9482 9483 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9484 @*/ 9485 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9486 { 9487 PetscErrorCode ierr; 9488 9489 PetscFunctionBegin; 9490 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9491 PetscValidType(A,1); 9492 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9493 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9494 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9495 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9496 PetscValidType(R,2); 9497 MatCheckPreallocated(R,2); 9498 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9499 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9500 PetscValidPointer(C,3); 9501 9502 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9503 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9504 MatCheckPreallocated(A,1); 9505 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9506 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9507 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9508 9509 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9510 PetscFunctionReturn(0); 9511 } 9512 9513 /*@ 9514 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9515 9516 Neighbor-wise Collective on Mat 9517 9518 Input Parameters: 9519 + A - the left matrix 9520 . B - the right matrix 9521 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9522 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9523 if the result is a dense matrix this is irrelevent 9524 9525 Output Parameters: 9526 . C - the product matrix 9527 9528 Notes: 9529 Unless scall is MAT_REUSE_MATRIX C will be created. 9530 9531 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 9532 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9533 9534 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9535 actually needed. 9536 9537 If you have many matrices with the same non-zero structure to multiply, you 9538 should either 9539 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9540 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9541 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 9542 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9543 9544 Level: intermediate 9545 9546 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9547 @*/ 9548 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9549 { 9550 PetscErrorCode ierr; 9551 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9552 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9553 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9554 Mat T; 9555 PetscBool istrans; 9556 9557 PetscFunctionBegin; 9558 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9559 PetscValidType(A,1); 9560 MatCheckPreallocated(A,1); 9561 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9562 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9563 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9564 PetscValidType(B,2); 9565 MatCheckPreallocated(B,2); 9566 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9567 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9568 PetscValidPointer(C,3); 9569 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9570 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9571 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9572 if (istrans) { 9573 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9574 ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9575 PetscFunctionReturn(0); 9576 } else { 9577 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9578 if (istrans) { 9579 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9580 ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr); 9581 PetscFunctionReturn(0); 9582 } 9583 } 9584 if (scall == MAT_REUSE_MATRIX) { 9585 PetscValidPointer(*C,5); 9586 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9587 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9588 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9589 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9590 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9591 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9592 PetscFunctionReturn(0); 9593 } 9594 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9595 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9596 9597 fA = A->ops->matmult; 9598 fB = B->ops->matmult; 9599 if (fB == fA) { 9600 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9601 mult = fB; 9602 } else { 9603 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9604 char multname[256]; 9605 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9606 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9607 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9608 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9609 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9610 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9611 if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9612 } 9613 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9614 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9615 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9616 PetscFunctionReturn(0); 9617 } 9618 9619 /*@ 9620 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9621 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9622 9623 Neighbor-wise Collective on Mat 9624 9625 Input Parameters: 9626 + A - the left matrix 9627 . B - the right matrix 9628 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9629 if C is a dense matrix this is irrelevent 9630 9631 Output Parameters: 9632 . C - the product matrix 9633 9634 Notes: 9635 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9636 actually needed. 9637 9638 This routine is currently implemented for 9639 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9640 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9641 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9642 9643 Level: intermediate 9644 9645 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173 9646 We should incorporate them into PETSc. 9647 9648 .seealso: MatMatMult(), MatMatMultNumeric() 9649 @*/ 9650 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9651 { 9652 PetscErrorCode ierr; 9653 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9654 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9655 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9656 9657 PetscFunctionBegin; 9658 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9659 PetscValidType(A,1); 9660 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9661 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9662 9663 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9664 PetscValidType(B,2); 9665 MatCheckPreallocated(B,2); 9666 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9667 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9668 PetscValidPointer(C,3); 9669 9670 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9671 if (fill == PETSC_DEFAULT) fill = 2.0; 9672 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9673 MatCheckPreallocated(A,1); 9674 9675 Asymbolic = A->ops->matmultsymbolic; 9676 Bsymbolic = B->ops->matmultsymbolic; 9677 if (Asymbolic == Bsymbolic) { 9678 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9679 symbolic = Bsymbolic; 9680 } else { /* dispatch based on the type of A and B */ 9681 char symbolicname[256]; 9682 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9683 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9684 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9685 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9686 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9687 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9688 if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9689 } 9690 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9691 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9692 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9693 PetscFunctionReturn(0); 9694 } 9695 9696 /*@ 9697 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9698 Call this routine after first calling MatMatMultSymbolic(). 9699 9700 Neighbor-wise Collective on Mat 9701 9702 Input Parameters: 9703 + A - the left matrix 9704 - B - the right matrix 9705 9706 Output Parameters: 9707 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9708 9709 Notes: 9710 C must have been created with MatMatMultSymbolic(). 9711 9712 This routine is currently implemented for 9713 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9714 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9715 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9716 9717 Level: intermediate 9718 9719 .seealso: MatMatMult(), MatMatMultSymbolic() 9720 @*/ 9721 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9722 { 9723 PetscErrorCode ierr; 9724 9725 PetscFunctionBegin; 9726 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9727 PetscFunctionReturn(0); 9728 } 9729 9730 /*@ 9731 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9732 9733 Neighbor-wise Collective on Mat 9734 9735 Input Parameters: 9736 + A - the left matrix 9737 . B - the right matrix 9738 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9739 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9740 9741 Output Parameters: 9742 . C - the product matrix 9743 9744 Notes: 9745 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9746 9747 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9748 9749 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9750 actually needed. 9751 9752 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9753 and for pairs of MPIDense matrices. 9754 9755 Options Database Keys: 9756 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9757 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9758 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9759 9760 Level: intermediate 9761 9762 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9763 @*/ 9764 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9765 { 9766 PetscErrorCode ierr; 9767 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9768 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9769 Mat T; 9770 PetscBool istrans; 9771 9772 PetscFunctionBegin; 9773 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9774 PetscValidType(A,1); 9775 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9776 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9777 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9778 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9779 PetscValidType(B,2); 9780 MatCheckPreallocated(B,2); 9781 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9782 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9783 PetscValidPointer(C,3); 9784 if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N); 9785 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9786 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9787 MatCheckPreallocated(A,1); 9788 9789 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9790 if (istrans) { 9791 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9792 ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr); 9793 PetscFunctionReturn(0); 9794 } 9795 fA = A->ops->mattransposemult; 9796 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9797 fB = B->ops->mattransposemult; 9798 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9799 if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9800 9801 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9802 if (scall == MAT_INITIAL_MATRIX) { 9803 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9804 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9805 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9806 } 9807 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9808 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9809 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9810 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9811 PetscFunctionReturn(0); 9812 } 9813 9814 /*@ 9815 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9816 9817 Neighbor-wise Collective on Mat 9818 9819 Input Parameters: 9820 + A - the left matrix 9821 . B - the right matrix 9822 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9823 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9824 9825 Output Parameters: 9826 . C - the product matrix 9827 9828 Notes: 9829 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9830 9831 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9832 9833 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9834 actually needed. 9835 9836 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9837 which inherit from SeqAIJ. C will be of same type as the input matrices. 9838 9839 Level: intermediate 9840 9841 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9842 @*/ 9843 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9844 { 9845 PetscErrorCode ierr; 9846 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9847 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9848 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9849 Mat T; 9850 PetscBool istrans; 9851 9852 PetscFunctionBegin; 9853 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9854 PetscValidType(A,1); 9855 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9856 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9857 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9858 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9859 PetscValidType(B,2); 9860 MatCheckPreallocated(B,2); 9861 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9862 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9863 PetscValidPointer(C,3); 9864 if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N); 9865 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9866 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9867 MatCheckPreallocated(A,1); 9868 9869 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9870 if (istrans) { 9871 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9872 ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9873 PetscFunctionReturn(0); 9874 } 9875 fA = A->ops->transposematmult; 9876 fB = B->ops->transposematmult; 9877 if (fB==fA) { 9878 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9879 transposematmult = fA; 9880 } else { 9881 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9882 char multname[256]; 9883 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 9884 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9885 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9886 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9887 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9888 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9889 if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9890 } 9891 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9892 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9893 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9894 PetscFunctionReturn(0); 9895 } 9896 9897 /*@ 9898 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9899 9900 Neighbor-wise Collective on Mat 9901 9902 Input Parameters: 9903 + A - the left matrix 9904 . B - the middle matrix 9905 . C - the right matrix 9906 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9907 - 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 9908 if the result is a dense matrix this is irrelevent 9909 9910 Output Parameters: 9911 . D - the product matrix 9912 9913 Notes: 9914 Unless scall is MAT_REUSE_MATRIX D will be created. 9915 9916 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9917 9918 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9919 actually needed. 9920 9921 If you have many matrices with the same non-zero structure to multiply, you 9922 should use MAT_REUSE_MATRIX in all calls but the first or 9923 9924 Level: intermediate 9925 9926 .seealso: MatMatMult, MatPtAP() 9927 @*/ 9928 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9929 { 9930 PetscErrorCode ierr; 9931 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9932 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9933 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9934 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9935 9936 PetscFunctionBegin; 9937 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9938 PetscValidType(A,1); 9939 MatCheckPreallocated(A,1); 9940 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9941 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9942 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9943 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9944 PetscValidType(B,2); 9945 MatCheckPreallocated(B,2); 9946 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9947 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9948 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9949 PetscValidPointer(C,3); 9950 MatCheckPreallocated(C,3); 9951 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9952 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9953 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9954 if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N); 9955 if (scall == MAT_REUSE_MATRIX) { 9956 PetscValidPointer(*D,6); 9957 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9958 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9959 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9960 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9961 PetscFunctionReturn(0); 9962 } 9963 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9964 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9965 9966 fA = A->ops->matmatmult; 9967 fB = B->ops->matmatmult; 9968 fC = C->ops->matmatmult; 9969 if (fA == fB && fA == fC) { 9970 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9971 mult = fA; 9972 } else { 9973 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9974 char multname[256]; 9975 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 9976 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9977 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9978 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9979 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9980 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 9981 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 9982 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9983 if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name); 9984 } 9985 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9986 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9987 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9988 PetscFunctionReturn(0); 9989 } 9990 9991 /*@ 9992 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9993 9994 Collective on Mat 9995 9996 Input Parameters: 9997 + mat - the matrix 9998 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9999 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10000 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10001 10002 Output Parameter: 10003 . matredundant - redundant matrix 10004 10005 Notes: 10006 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10007 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10008 10009 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10010 calling it. 10011 10012 Level: advanced 10013 10014 10015 .seealso: MatDestroy() 10016 @*/ 10017 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10018 { 10019 PetscErrorCode ierr; 10020 MPI_Comm comm; 10021 PetscMPIInt size; 10022 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10023 Mat_Redundant *redund=NULL; 10024 PetscSubcomm psubcomm=NULL; 10025 MPI_Comm subcomm_in=subcomm; 10026 Mat *matseq; 10027 IS isrow,iscol; 10028 PetscBool newsubcomm=PETSC_FALSE; 10029 10030 PetscFunctionBegin; 10031 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10032 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10033 PetscValidPointer(*matredundant,5); 10034 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10035 } 10036 10037 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10038 if (size == 1 || nsubcomm == 1) { 10039 if (reuse == MAT_INITIAL_MATRIX) { 10040 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10041 } else { 10042 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"); 10043 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10044 } 10045 PetscFunctionReturn(0); 10046 } 10047 10048 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10049 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10050 MatCheckPreallocated(mat,1); 10051 10052 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10053 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10054 /* create psubcomm, then get subcomm */ 10055 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10056 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10057 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10058 10059 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10060 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10061 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10062 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10063 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10064 newsubcomm = PETSC_TRUE; 10065 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10066 } 10067 10068 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10069 if (reuse == MAT_INITIAL_MATRIX) { 10070 mloc_sub = PETSC_DECIDE; 10071 nloc_sub = PETSC_DECIDE; 10072 if (bs < 1) { 10073 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10074 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10075 } else { 10076 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10077 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10078 } 10079 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10080 rstart = rend - mloc_sub; 10081 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10082 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10083 } else { /* reuse == MAT_REUSE_MATRIX */ 10084 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"); 10085 /* retrieve subcomm */ 10086 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10087 redund = (*matredundant)->redundant; 10088 isrow = redund->isrow; 10089 iscol = redund->iscol; 10090 matseq = redund->matseq; 10091 } 10092 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10093 10094 /* get matredundant over subcomm */ 10095 if (reuse == MAT_INITIAL_MATRIX) { 10096 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10097 10098 /* create a supporting struct and attach it to C for reuse */ 10099 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10100 (*matredundant)->redundant = redund; 10101 redund->isrow = isrow; 10102 redund->iscol = iscol; 10103 redund->matseq = matseq; 10104 if (newsubcomm) { 10105 redund->subcomm = subcomm; 10106 } else { 10107 redund->subcomm = MPI_COMM_NULL; 10108 } 10109 } else { 10110 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10111 } 10112 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10113 PetscFunctionReturn(0); 10114 } 10115 10116 /*@C 10117 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10118 a given 'mat' object. Each submatrix can span multiple procs. 10119 10120 Collective on Mat 10121 10122 Input Parameters: 10123 + mat - the matrix 10124 . subcomm - the subcommunicator obtained by com_split(comm) 10125 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10126 10127 Output Parameter: 10128 . subMat - 'parallel submatrices each spans a given subcomm 10129 10130 Notes: 10131 The submatrix partition across processors is dictated by 'subComm' a 10132 communicator obtained by com_split(comm). The comm_split 10133 is not restriced to be grouped with consecutive original ranks. 10134 10135 Due the comm_split() usage, the parallel layout of the submatrices 10136 map directly to the layout of the original matrix [wrt the local 10137 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10138 into the 'DiagonalMat' of the subMat, hence it is used directly from 10139 the subMat. However the offDiagMat looses some columns - and this is 10140 reconstructed with MatSetValues() 10141 10142 Level: advanced 10143 10144 10145 .seealso: MatCreateSubMatrices() 10146 @*/ 10147 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10148 { 10149 PetscErrorCode ierr; 10150 PetscMPIInt commsize,subCommSize; 10151 10152 PetscFunctionBegin; 10153 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10154 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10155 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10156 10157 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"); 10158 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10159 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10160 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10161 PetscFunctionReturn(0); 10162 } 10163 10164 /*@ 10165 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10166 10167 Not Collective 10168 10169 Input Arguments: 10170 mat - matrix to extract local submatrix from 10171 isrow - local row indices for submatrix 10172 iscol - local column indices for submatrix 10173 10174 Output Arguments: 10175 submat - the submatrix 10176 10177 Level: intermediate 10178 10179 Notes: 10180 The submat should be returned with MatRestoreLocalSubMatrix(). 10181 10182 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10183 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10184 10185 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10186 MatSetValuesBlockedLocal() will also be implemented. 10187 10188 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10189 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10190 10191 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10192 @*/ 10193 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10194 { 10195 PetscErrorCode ierr; 10196 10197 PetscFunctionBegin; 10198 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10199 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10200 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10201 PetscCheckSameComm(isrow,2,iscol,3); 10202 PetscValidPointer(submat,4); 10203 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10204 10205 if (mat->ops->getlocalsubmatrix) { 10206 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10207 } else { 10208 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10209 } 10210 PetscFunctionReturn(0); 10211 } 10212 10213 /*@ 10214 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10215 10216 Not Collective 10217 10218 Input Arguments: 10219 mat - matrix to extract local submatrix from 10220 isrow - local row indices for submatrix 10221 iscol - local column indices for submatrix 10222 submat - the submatrix 10223 10224 Level: intermediate 10225 10226 .seealso: MatGetLocalSubMatrix() 10227 @*/ 10228 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10229 { 10230 PetscErrorCode ierr; 10231 10232 PetscFunctionBegin; 10233 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10234 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10235 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10236 PetscCheckSameComm(isrow,2,iscol,3); 10237 PetscValidPointer(submat,4); 10238 if (*submat) { 10239 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10240 } 10241 10242 if (mat->ops->restorelocalsubmatrix) { 10243 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10244 } else { 10245 ierr = MatDestroy(submat);CHKERRQ(ierr); 10246 } 10247 *submat = NULL; 10248 PetscFunctionReturn(0); 10249 } 10250 10251 /* --------------------------------------------------------*/ 10252 /*@ 10253 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10254 10255 Collective on Mat 10256 10257 Input Parameter: 10258 . mat - the matrix 10259 10260 Output Parameter: 10261 . is - if any rows have zero diagonals this contains the list of them 10262 10263 Level: developer 10264 10265 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10266 @*/ 10267 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10268 { 10269 PetscErrorCode ierr; 10270 10271 PetscFunctionBegin; 10272 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10273 PetscValidType(mat,1); 10274 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10275 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10276 10277 if (!mat->ops->findzerodiagonals) { 10278 Vec diag; 10279 const PetscScalar *a; 10280 PetscInt *rows; 10281 PetscInt rStart, rEnd, r, nrow = 0; 10282 10283 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10284 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10285 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10286 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10287 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10288 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10289 nrow = 0; 10290 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10291 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10292 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10293 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10294 } else { 10295 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10296 } 10297 PetscFunctionReturn(0); 10298 } 10299 10300 /*@ 10301 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10302 10303 Collective on Mat 10304 10305 Input Parameter: 10306 . mat - the matrix 10307 10308 Output Parameter: 10309 . is - contains the list of rows with off block diagonal entries 10310 10311 Level: developer 10312 10313 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10314 @*/ 10315 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10316 { 10317 PetscErrorCode ierr; 10318 10319 PetscFunctionBegin; 10320 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10321 PetscValidType(mat,1); 10322 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10323 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10324 10325 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10326 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10327 PetscFunctionReturn(0); 10328 } 10329 10330 /*@C 10331 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10332 10333 Collective on Mat 10334 10335 Input Parameters: 10336 . mat - the matrix 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: MatInvertBockDiagonalMat 10347 @*/ 10348 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const 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->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10357 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10358 PetscFunctionReturn(0); 10359 } 10360 10361 /*@C 10362 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10363 10364 Collective on Mat 10365 10366 Input Parameters: 10367 + mat - the matrix 10368 . nblocks - the number of blocks 10369 - bsizes - the size of each block 10370 10371 Output Parameters: 10372 . values - the block inverses in column major order (FORTRAN-like) 10373 10374 Note: 10375 This routine is not available from Fortran. 10376 10377 Level: advanced 10378 10379 .seealso: MatInvertBockDiagonal() 10380 @*/ 10381 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10382 { 10383 PetscErrorCode ierr; 10384 10385 PetscFunctionBegin; 10386 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10387 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10388 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10389 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10390 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10391 PetscFunctionReturn(0); 10392 } 10393 10394 /*@ 10395 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10396 10397 Collective on Mat 10398 10399 Input Parameters: 10400 . A - the matrix 10401 10402 Output Parameters: 10403 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10404 10405 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10406 10407 Level: advanced 10408 10409 .seealso: MatInvertBockDiagonal() 10410 @*/ 10411 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10412 { 10413 PetscErrorCode ierr; 10414 const PetscScalar *vals; 10415 PetscInt *dnnz; 10416 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10417 10418 PetscFunctionBegin; 10419 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10420 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10421 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10422 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10423 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10424 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10425 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10426 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10427 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10428 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10429 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10430 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10431 for (i = rstart/bs; i < rend/bs; i++) { 10432 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10433 } 10434 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10435 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10436 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10437 PetscFunctionReturn(0); 10438 } 10439 10440 /*@C 10441 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10442 via MatTransposeColoringCreate(). 10443 10444 Collective on MatTransposeColoring 10445 10446 Input Parameter: 10447 . c - coloring context 10448 10449 Level: intermediate 10450 10451 .seealso: MatTransposeColoringCreate() 10452 @*/ 10453 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10454 { 10455 PetscErrorCode ierr; 10456 MatTransposeColoring matcolor=*c; 10457 10458 PetscFunctionBegin; 10459 if (!matcolor) PetscFunctionReturn(0); 10460 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10461 10462 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10463 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10464 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10465 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10466 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10467 if (matcolor->brows>0) { 10468 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10469 } 10470 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10471 PetscFunctionReturn(0); 10472 } 10473 10474 /*@C 10475 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10476 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10477 MatTransposeColoring to sparse B. 10478 10479 Collective on MatTransposeColoring 10480 10481 Input Parameters: 10482 + B - sparse matrix B 10483 . Btdense - symbolic dense matrix B^T 10484 - coloring - coloring context created with MatTransposeColoringCreate() 10485 10486 Output Parameter: 10487 . Btdense - dense matrix B^T 10488 10489 Level: advanced 10490 10491 Notes: 10492 These are used internally for some implementations of MatRARt() 10493 10494 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10495 10496 @*/ 10497 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10498 { 10499 PetscErrorCode ierr; 10500 10501 PetscFunctionBegin; 10502 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10503 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10504 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10505 10506 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10507 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10508 PetscFunctionReturn(0); 10509 } 10510 10511 /*@C 10512 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10513 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10514 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10515 Csp from Cden. 10516 10517 Collective on MatTransposeColoring 10518 10519 Input Parameters: 10520 + coloring - coloring context created with MatTransposeColoringCreate() 10521 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10522 10523 Output Parameter: 10524 . Csp - sparse matrix 10525 10526 Level: advanced 10527 10528 Notes: 10529 These are used internally for some implementations of MatRARt() 10530 10531 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10532 10533 @*/ 10534 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10535 { 10536 PetscErrorCode ierr; 10537 10538 PetscFunctionBegin; 10539 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10540 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10541 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10542 10543 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10544 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10545 PetscFunctionReturn(0); 10546 } 10547 10548 /*@C 10549 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10550 10551 Collective on Mat 10552 10553 Input Parameters: 10554 + mat - the matrix product C 10555 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10556 10557 Output Parameter: 10558 . color - the new coloring context 10559 10560 Level: intermediate 10561 10562 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10563 MatTransColoringApplyDenToSp() 10564 @*/ 10565 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10566 { 10567 MatTransposeColoring c; 10568 MPI_Comm comm; 10569 PetscErrorCode ierr; 10570 10571 PetscFunctionBegin; 10572 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10573 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10574 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10575 10576 c->ctype = iscoloring->ctype; 10577 if (mat->ops->transposecoloringcreate) { 10578 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10579 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10580 10581 *color = c; 10582 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10583 PetscFunctionReturn(0); 10584 } 10585 10586 /*@ 10587 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10588 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10589 same, otherwise it will be larger 10590 10591 Not Collective 10592 10593 Input Parameter: 10594 . A - the matrix 10595 10596 Output Parameter: 10597 . state - the current state 10598 10599 Notes: 10600 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10601 different matrices 10602 10603 Level: intermediate 10604 10605 @*/ 10606 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10607 { 10608 PetscFunctionBegin; 10609 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10610 *state = mat->nonzerostate; 10611 PetscFunctionReturn(0); 10612 } 10613 10614 /*@ 10615 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10616 matrices from each processor 10617 10618 Collective 10619 10620 Input Parameters: 10621 + comm - the communicators the parallel matrix will live on 10622 . seqmat - the input sequential matrices 10623 . n - number of local columns (or PETSC_DECIDE) 10624 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10625 10626 Output Parameter: 10627 . mpimat - the parallel matrix generated 10628 10629 Level: advanced 10630 10631 Notes: 10632 The number of columns of the matrix in EACH processor MUST be the same. 10633 10634 @*/ 10635 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10636 { 10637 PetscErrorCode ierr; 10638 10639 PetscFunctionBegin; 10640 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10641 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"); 10642 10643 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10644 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10645 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10646 PetscFunctionReturn(0); 10647 } 10648 10649 /*@ 10650 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10651 ranks' ownership ranges. 10652 10653 Collective on A 10654 10655 Input Parameters: 10656 + A - the matrix to create subdomains from 10657 - N - requested number of subdomains 10658 10659 10660 Output Parameters: 10661 + n - number of subdomains resulting on this rank 10662 - iss - IS list with indices of subdomains on this rank 10663 10664 Level: advanced 10665 10666 Notes: 10667 number of subdomains must be smaller than the communicator size 10668 @*/ 10669 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10670 { 10671 MPI_Comm comm,subcomm; 10672 PetscMPIInt size,rank,color; 10673 PetscInt rstart,rend,k; 10674 PetscErrorCode ierr; 10675 10676 PetscFunctionBegin; 10677 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10678 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10679 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10680 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); 10681 *n = 1; 10682 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10683 color = rank/k; 10684 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10685 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10686 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10687 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10688 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10689 PetscFunctionReturn(0); 10690 } 10691 10692 /*@ 10693 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10694 10695 If the interpolation and restriction operators are the same, uses MatPtAP. 10696 If they are not the same, use MatMatMatMult. 10697 10698 Once the coarse grid problem is constructed, correct for interpolation operators 10699 that are not of full rank, which can legitimately happen in the case of non-nested 10700 geometric multigrid. 10701 10702 Input Parameters: 10703 + restrct - restriction operator 10704 . dA - fine grid matrix 10705 . interpolate - interpolation operator 10706 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10707 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10708 10709 Output Parameters: 10710 . A - the Galerkin coarse matrix 10711 10712 Options Database Key: 10713 . -pc_mg_galerkin <both,pmat,mat,none> 10714 10715 Level: developer 10716 10717 .seealso: MatPtAP(), MatMatMatMult() 10718 @*/ 10719 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10720 { 10721 PetscErrorCode ierr; 10722 IS zerorows; 10723 Vec diag; 10724 10725 PetscFunctionBegin; 10726 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10727 /* Construct the coarse grid matrix */ 10728 if (interpolate == restrct) { 10729 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10730 } else { 10731 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10732 } 10733 10734 /* If the interpolation matrix is not of full rank, A will have zero rows. 10735 This can legitimately happen in the case of non-nested geometric multigrid. 10736 In that event, we set the rows of the matrix to the rows of the identity, 10737 ignoring the equations (as the RHS will also be zero). */ 10738 10739 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10740 10741 if (zerorows != NULL) { /* if there are any zero rows */ 10742 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10743 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10744 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10745 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10746 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10747 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10748 } 10749 PetscFunctionReturn(0); 10750 } 10751 10752 /*@C 10753 MatSetOperation - Allows user to set a matrix operation for any matrix type 10754 10755 Logically Collective on Mat 10756 10757 Input Parameters: 10758 + mat - the matrix 10759 . op - the name of the operation 10760 - f - the function that provides the operation 10761 10762 Level: developer 10763 10764 Usage: 10765 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10766 $ ierr = MatCreateXXX(comm,...&A); 10767 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10768 10769 Notes: 10770 See the file include/petscmat.h for a complete list of matrix 10771 operations, which all have the form MATOP_<OPERATION>, where 10772 <OPERATION> is the name (in all capital letters) of the 10773 user interface routine (e.g., MatMult() -> MATOP_MULT). 10774 10775 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10776 sequence as the usual matrix interface routines, since they 10777 are intended to be accessed via the usual matrix interface 10778 routines, e.g., 10779 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10780 10781 In particular each function MUST return an error code of 0 on success and 10782 nonzero on failure. 10783 10784 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10785 10786 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10787 @*/ 10788 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10789 { 10790 PetscFunctionBegin; 10791 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10792 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10793 mat->ops->viewnative = mat->ops->view; 10794 } 10795 (((void(**)(void))mat->ops)[op]) = f; 10796 PetscFunctionReturn(0); 10797 } 10798 10799 /*@C 10800 MatGetOperation - Gets a matrix operation for any matrix type. 10801 10802 Not Collective 10803 10804 Input Parameters: 10805 + mat - the matrix 10806 - op - the name of the operation 10807 10808 Output Parameter: 10809 . f - the function that provides the operation 10810 10811 Level: developer 10812 10813 Usage: 10814 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10815 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10816 10817 Notes: 10818 See the file include/petscmat.h for a complete list of matrix 10819 operations, which all have the form MATOP_<OPERATION>, where 10820 <OPERATION> is the name (in all capital letters) of the 10821 user interface routine (e.g., MatMult() -> MATOP_MULT). 10822 10823 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10824 10825 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10826 @*/ 10827 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10828 { 10829 PetscFunctionBegin; 10830 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10831 *f = (((void (**)(void))mat->ops)[op]); 10832 PetscFunctionReturn(0); 10833 } 10834 10835 /*@ 10836 MatHasOperation - Determines whether the given matrix supports the particular 10837 operation. 10838 10839 Not Collective 10840 10841 Input Parameters: 10842 + mat - the matrix 10843 - op - the operation, for example, MATOP_GET_DIAGONAL 10844 10845 Output Parameter: 10846 . has - either PETSC_TRUE or PETSC_FALSE 10847 10848 Level: advanced 10849 10850 Notes: 10851 See the file include/petscmat.h for a complete list of matrix 10852 operations, which all have the form MATOP_<OPERATION>, where 10853 <OPERATION> is the name (in all capital letters) of the 10854 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10855 10856 .seealso: MatCreateShell() 10857 @*/ 10858 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10859 { 10860 PetscErrorCode ierr; 10861 10862 PetscFunctionBegin; 10863 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10864 PetscValidType(mat,1); 10865 PetscValidPointer(has,3); 10866 if (mat->ops->hasoperation) { 10867 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10868 } else { 10869 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10870 else { 10871 *has = PETSC_FALSE; 10872 if (op == MATOP_CREATE_SUBMATRIX) { 10873 PetscMPIInt size; 10874 10875 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10876 if (size == 1) { 10877 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10878 } 10879 } 10880 } 10881 } 10882 PetscFunctionReturn(0); 10883 } 10884 10885 /*@ 10886 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10887 of the matrix are congruent 10888 10889 Collective on mat 10890 10891 Input Parameters: 10892 . mat - the matrix 10893 10894 Output Parameter: 10895 . cong - either PETSC_TRUE or PETSC_FALSE 10896 10897 Level: beginner 10898 10899 Notes: 10900 10901 .seealso: MatCreate(), MatSetSizes() 10902 @*/ 10903 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10904 { 10905 PetscErrorCode ierr; 10906 10907 PetscFunctionBegin; 10908 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10909 PetscValidType(mat,1); 10910 PetscValidPointer(cong,2); 10911 if (!mat->rmap || !mat->cmap) { 10912 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10913 PetscFunctionReturn(0); 10914 } 10915 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10916 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 10917 if (*cong) mat->congruentlayouts = 1; 10918 else mat->congruentlayouts = 0; 10919 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10920 PetscFunctionReturn(0); 10921 } 10922 10923 /*@ 10924 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 10925 e.g., matrx product of MatPtAP. 10926 10927 Collective on mat 10928 10929 Input Parameters: 10930 . mat - the matrix 10931 10932 Output Parameter: 10933 . mat - the matrix with intermediate data structures released 10934 10935 Level: advanced 10936 10937 Notes: 10938 10939 .seealso: MatPtAP(), MatMatMult() 10940 @*/ 10941 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 10942 { 10943 PetscErrorCode ierr; 10944 10945 PetscFunctionBegin; 10946 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10947 PetscValidType(mat,1); 10948 if (mat->ops->freeintermediatedatastructures) { 10949 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 10950 } 10951 PetscFunctionReturn(0); 10952 } 10953