1 2 /* 3 This is where the abstract matrix operations are defined that are 4 used for finite difference computations of Jacobians using coloring. 5 */ 6 7 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 8 #include <petsc/private/isimpl.h> 9 10 PetscErrorCode MatFDColoringSetF(MatFDColoring fd,Vec F) 11 { 12 PetscErrorCode ierr; 13 14 PetscFunctionBegin; 15 if (F) { 16 ierr = VecCopy(F,fd->w1);CHKERRQ(ierr); 17 fd->fset = PETSC_TRUE; 18 } else { 19 fd->fset = PETSC_FALSE; 20 } 21 PetscFunctionReturn(0); 22 } 23 24 #include <petscdraw.h> 25 static PetscErrorCode MatFDColoringView_Draw_Zoom(PetscDraw draw,void *Aa) 26 { 27 MatFDColoring fd = (MatFDColoring)Aa; 28 PetscErrorCode ierr; 29 PetscInt i,j,nz,row; 30 PetscReal x,y; 31 MatEntry *Jentry=fd->matentry; 32 33 PetscFunctionBegin; 34 /* loop over colors */ 35 nz = 0; 36 for (i=0; i<fd->ncolors; i++) { 37 for (j=0; j<fd->nrows[i]; j++) { 38 row = Jentry[nz].row; 39 y = fd->M - row - fd->rstart; 40 x = (PetscReal)Jentry[nz++].col; 41 ierr = PetscDrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1);CHKERRQ(ierr); 42 } 43 } 44 PetscFunctionReturn(0); 45 } 46 47 static PetscErrorCode MatFDColoringView_Draw(MatFDColoring fd,PetscViewer viewer) 48 { 49 PetscErrorCode ierr; 50 PetscBool isnull; 51 PetscDraw draw; 52 PetscReal xr,yr,xl,yl,h,w; 53 54 PetscFunctionBegin; 55 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 56 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 57 if (isnull) PetscFunctionReturn(0); 58 59 xr = fd->N; yr = fd->M; h = yr/10.0; w = xr/10.0; 60 xr += w; yr += h; xl = -w; yl = -h; 61 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 62 ierr = PetscObjectCompose((PetscObject)fd,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 63 ierr = PetscDrawZoom(draw,MatFDColoringView_Draw_Zoom,fd);CHKERRQ(ierr); 64 ierr = PetscObjectCompose((PetscObject)fd,"Zoomviewer",NULL);CHKERRQ(ierr); 65 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 66 PetscFunctionReturn(0); 67 } 68 69 /*@C 70 MatFDColoringView - Views a finite difference coloring context. 71 72 Collective on MatFDColoring 73 74 Input Parameters: 75 + c - the coloring context 76 - viewer - visualization context 77 78 Level: intermediate 79 80 Notes: 81 The available visualization contexts include 82 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 83 . PETSC_VIEWER_STDOUT_WORLD - synchronized standard 84 output where only the first processor opens 85 the file. All other processors send their 86 data to the first processor to print. 87 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 88 89 Notes: 90 Since PETSc uses only a small number of basic colors (currently 33), if the coloring 91 involves more than 33 then some seemingly identical colors are displayed making it look 92 like an illegal coloring. This is just a graphical artifact. 93 94 .seealso: MatFDColoringCreate() 95 96 @*/ 97 PetscErrorCode MatFDColoringView(MatFDColoring c,PetscViewer viewer) 98 { 99 PetscErrorCode ierr; 100 PetscInt i,j; 101 PetscBool isdraw,iascii; 102 PetscViewerFormat format; 103 104 PetscFunctionBegin; 105 PetscValidHeaderSpecific(c,MAT_FDCOLORING_CLASSID,1); 106 if (!viewer) { 107 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)c),&viewer);CHKERRQ(ierr); 108 } 109 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 110 PetscCheckSameComm(c,1,viewer,2); 111 112 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 113 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 114 if (isdraw) { 115 ierr = MatFDColoringView_Draw(c,viewer);CHKERRQ(ierr); 116 } else if (iascii) { 117 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)c,viewer);CHKERRQ(ierr); 118 ierr = PetscViewerASCIIPrintf(viewer," Error tolerance=%g\n",(double)c->error_rel);CHKERRQ(ierr); 119 ierr = PetscViewerASCIIPrintf(viewer," Umin=%g\n",(double)c->umin);CHKERRQ(ierr); 120 ierr = PetscViewerASCIIPrintf(viewer," Number of colors=%D\n",c->ncolors);CHKERRQ(ierr); 121 122 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 123 if (format != PETSC_VIEWER_ASCII_INFO) { 124 PetscInt row,col,nz; 125 nz = 0; 126 for (i=0; i<c->ncolors; i++) { 127 ierr = PetscViewerASCIIPrintf(viewer," Information for color %D\n",i);CHKERRQ(ierr); 128 ierr = PetscViewerASCIIPrintf(viewer," Number of columns %D\n",c->ncolumns[i]);CHKERRQ(ierr); 129 for (j=0; j<c->ncolumns[i]; j++) { 130 ierr = PetscViewerASCIIPrintf(viewer," %D\n",c->columns[i][j]);CHKERRQ(ierr); 131 } 132 ierr = PetscViewerASCIIPrintf(viewer," Number of rows %D\n",c->nrows[i]);CHKERRQ(ierr); 133 if (c->matentry) { 134 for (j=0; j<c->nrows[i]; j++) { 135 row = c->matentry[nz].row; 136 col = c->matentry[nz++].col; 137 ierr = PetscViewerASCIIPrintf(viewer," %D %D \n",row,col);CHKERRQ(ierr); 138 } 139 } 140 } 141 } 142 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 143 } 144 PetscFunctionReturn(0); 145 } 146 147 /*@ 148 MatFDColoringSetParameters - Sets the parameters for the sparse approximation of 149 a Jacobian matrix using finite differences. 150 151 Logically Collective on MatFDColoring 152 153 The Jacobian is estimated with the differencing approximation 154 .vb 155 F'(u)_{:,i} = [F(u+h*dx_{i}) - F(u)]/h where 156 htype = 'ds': 157 h = error_rel*u[i] if abs(u[i]) > umin 158 = +/- error_rel*umin otherwise, with +/- determined by the sign of u[i] 159 dx_{i} = (0, ... 1, .... 0) 160 161 htype = 'wp': 162 h = error_rel * sqrt(1 + ||u||) 163 .ve 164 165 Input Parameters: 166 + coloring - the coloring context 167 . error_rel - relative error 168 - umin - minimum allowable u-value magnitude 169 170 Level: advanced 171 172 .seealso: MatFDColoringCreate(), MatFDColoringSetFromOptions() 173 174 @*/ 175 PetscErrorCode MatFDColoringSetParameters(MatFDColoring matfd,PetscReal error,PetscReal umin) 176 { 177 PetscFunctionBegin; 178 PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 179 PetscValidLogicalCollectiveReal(matfd,error,2); 180 PetscValidLogicalCollectiveReal(matfd,umin,3); 181 if (error != PETSC_DEFAULT) matfd->error_rel = error; 182 if (umin != PETSC_DEFAULT) matfd->umin = umin; 183 PetscFunctionReturn(0); 184 } 185 186 /*@ 187 MatFDColoringSetBlockSize - Sets block size for efficient inserting entries of Jacobian matrix. 188 189 Logically Collective on MatFDColoring 190 191 Input Parameters: 192 + coloring - the coloring context 193 . brows - number of rows in the block 194 - bcols - number of columns in the block 195 196 Level: intermediate 197 198 .seealso: MatFDColoringCreate(), MatFDColoringSetFromOptions() 199 200 @*/ 201 PetscErrorCode MatFDColoringSetBlockSize(MatFDColoring matfd,PetscInt brows,PetscInt bcols) 202 { 203 PetscFunctionBegin; 204 PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 205 PetscValidLogicalCollectiveInt(matfd,brows,2); 206 PetscValidLogicalCollectiveInt(matfd,bcols,3); 207 if (brows != PETSC_DEFAULT) matfd->brows = brows; 208 if (bcols != PETSC_DEFAULT) matfd->bcols = bcols; 209 PetscFunctionReturn(0); 210 } 211 212 /*@ 213 MatFDColoringSetUp - Sets up the internal data structures of matrix coloring context for the later use. 214 215 Collective on Mat 216 217 Input Parameters: 218 + mat - the matrix containing the nonzero structure of the Jacobian 219 . iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring() 220 - color - the matrix coloring context 221 222 Level: beginner 223 224 Notes: When the coloring type is IS_COLORING_LOCAL the coloring is in the local ordering of the unknowns. 225 226 .seealso: MatFDColoringCreate(), MatFDColoringDestroy() 227 @*/ 228 PetscErrorCode MatFDColoringSetUp(Mat mat,ISColoring iscoloring,MatFDColoring color) 229 { 230 PetscErrorCode ierr; 231 PetscBool eq; 232 233 PetscFunctionBegin; 234 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 235 PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,3); 236 if (color->setupcalled) PetscFunctionReturn(0); 237 ierr = PetscObjectCompareId((PetscObject)mat,color->matid,&eq);CHKERRQ(ierr); 238 if (!eq) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix used with MatFDColoringSetUp() must be that used with MatFDColoringCreate()"); 239 240 ierr = PetscLogEventBegin(MAT_FDColoringSetUp,mat,0,0,0);CHKERRQ(ierr); 241 if (mat->ops->fdcoloringsetup) { 242 ierr = (*mat->ops->fdcoloringsetup)(mat,iscoloring,color);CHKERRQ(ierr); 243 } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 244 245 color->setupcalled = PETSC_TRUE; 246 ierr = PetscLogEventEnd(MAT_FDColoringSetUp,mat,0,0,0);CHKERRQ(ierr); 247 PetscFunctionReturn(0); 248 } 249 250 /*@C 251 MatFDColoringGetFunction - Gets the function to use for computing the Jacobian. 252 253 Not Collective 254 255 Input Parameters: 256 . coloring - the coloring context 257 258 Output Parameters: 259 + f - the function 260 - fctx - the optional user-defined function context 261 262 Level: intermediate 263 264 .seealso: MatFDColoringCreate(), MatFDColoringSetFunction(), MatFDColoringSetFromOptions() 265 266 @*/ 267 PetscErrorCode MatFDColoringGetFunction(MatFDColoring matfd,PetscErrorCode (**f)(void),void **fctx) 268 { 269 PetscFunctionBegin; 270 PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 271 if (f) *f = matfd->f; 272 if (fctx) *fctx = matfd->fctx; 273 PetscFunctionReturn(0); 274 } 275 276 /*@C 277 MatFDColoringSetFunction - Sets the function to use for computing the Jacobian. 278 279 Logically Collective on MatFDColoring 280 281 Input Parameters: 282 + coloring - the coloring context 283 . f - the function 284 - fctx - the optional user-defined function context 285 286 Calling sequence of (*f) function: 287 For SNES: PetscErrorCode (*f)(SNES,Vec,Vec,void*) 288 If not using SNES: PetscErrorCode (*f)(void *dummy,Vec,Vec,void*) and dummy is ignored 289 290 Level: advanced 291 292 Notes: 293 This function is usually used automatically by SNES (when one uses SNESSetJacobian() with the argument 294 SNESComputeJacobianDefaultColor()) and only needs to be used by someone computing a matrix via coloring directly by 295 calling MatFDColoringApply() 296 297 Fortran Notes: 298 In Fortran you must call MatFDColoringSetFunction() for a coloring object to 299 be used without SNES or within the SNES solvers. 300 301 .seealso: MatFDColoringCreate(), MatFDColoringGetFunction(), MatFDColoringSetFromOptions() 302 303 @*/ 304 PetscErrorCode MatFDColoringSetFunction(MatFDColoring matfd,PetscErrorCode (*f)(void),void *fctx) 305 { 306 PetscFunctionBegin; 307 PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 308 matfd->f = f; 309 matfd->fctx = fctx; 310 PetscFunctionReturn(0); 311 } 312 313 /*@ 314 MatFDColoringSetFromOptions - Sets coloring finite difference parameters from 315 the options database. 316 317 Collective on MatFDColoring 318 319 The Jacobian, F'(u), is estimated with the differencing approximation 320 .vb 321 F'(u)_{:,i} = [F(u+h*dx_{i}) - F(u)]/h where 322 h = error_rel*u[i] if abs(u[i]) > umin 323 = +/- error_rel*umin otherwise, with +/- determined by the sign of u[i] 324 dx_{i} = (0, ... 1, .... 0) 325 .ve 326 327 Input Parameter: 328 . coloring - the coloring context 329 330 Options Database Keys: 331 + -mat_fd_coloring_err <err> - Sets <err> (square root of relative error in the function) 332 . -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude 333 . -mat_fd_type - "wp" or "ds" (see MATMFFD_WP or MATMFFD_DS) 334 . -mat_fd_coloring_view - Activates basic viewing 335 . -mat_fd_coloring_view ::ascii_info - Activates viewing info 336 - -mat_fd_coloring_view draw - Activates drawing 337 338 Level: intermediate 339 340 .seealso: MatFDColoringCreate(), MatFDColoringView(), MatFDColoringSetParameters() 341 342 @*/ 343 PetscErrorCode MatFDColoringSetFromOptions(MatFDColoring matfd) 344 { 345 PetscErrorCode ierr; 346 PetscBool flg; 347 char value[3]; 348 349 PetscFunctionBegin; 350 PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 351 352 ierr = PetscObjectOptionsBegin((PetscObject)matfd);CHKERRQ(ierr); 353 ierr = PetscOptionsReal("-mat_fd_coloring_err","Square root of relative error in function","MatFDColoringSetParameters",matfd->error_rel,&matfd->error_rel,0);CHKERRQ(ierr); 354 ierr = PetscOptionsReal("-mat_fd_coloring_umin","Minimum allowable u magnitude","MatFDColoringSetParameters",matfd->umin,&matfd->umin,0);CHKERRQ(ierr); 355 ierr = PetscOptionsString("-mat_fd_type","Algorithm to compute h, wp or ds","MatFDColoringCreate",matfd->htype,value,3,&flg);CHKERRQ(ierr); 356 if (flg) { 357 if (value[0] == 'w' && value[1] == 'p') matfd->htype = "wp"; 358 else if (value[0] == 'd' && value[1] == 's') matfd->htype = "ds"; 359 else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown finite differencing type %s",value); 360 } 361 ierr = PetscOptionsInt("-mat_fd_coloring_brows","Number of block rows","MatFDColoringSetBlockSize",matfd->brows,&matfd->brows,NULL);CHKERRQ(ierr); 362 ierr = PetscOptionsInt("-mat_fd_coloring_bcols","Number of block columns","MatFDColoringSetBlockSize",matfd->bcols,&matfd->bcols,&flg);CHKERRQ(ierr); 363 if (flg && matfd->bcols > matfd->ncolors) { 364 /* input bcols cannot be > matfd->ncolors, thus set it as ncolors */ 365 matfd->bcols = matfd->ncolors; 366 } 367 368 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 369 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)matfd);CHKERRQ(ierr); 370 PetscOptionsEnd();CHKERRQ(ierr); 371 PetscFunctionReturn(0); 372 } 373 374 /*@C 375 MatFDColoringSetType - Sets the approach for computing the finite difference parameter 376 377 Collective on MatFDColoring 378 379 Input Parameters: 380 + coloring - the coloring context 381 - type - either MATMFFD_WP or MATMFFD_DS 382 383 Options Database Keys: 384 . -mat_fd_type - "wp" or "ds" 385 386 Note: It is goofy that the argument type is MatMFFDType since the MatFDColoring actually computes the matrix entries 387 but the process of computing the entries is the same as as with the MatMFFD operation so we should reuse the names instead of 388 introducing another one. 389 390 Level: intermediate 391 392 .seealso: MatFDColoringCreate(), MatFDColoringView(), MatFDColoringSetParameters() 393 394 @*/ 395 PetscErrorCode MatFDColoringSetType(MatFDColoring matfd,MatMFFDType type) 396 { 397 PetscFunctionBegin; 398 PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 399 /* 400 It is goofy to handle the strings this way but currently there is no code to free a dynamically created matfd->htype 401 and this function is being provided as patch for a release so it shouldn't change the implementaton 402 */ 403 if (type[0] == 'w' && type[1] == 'p') matfd->htype = "wp"; 404 else if (type[0] == 'd' && type[1] == 's') matfd->htype = "ds"; 405 else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown finite differencing type %s",type); 406 PetscFunctionReturn(0); 407 } 408 409 PetscErrorCode MatFDColoringViewFromOptions(MatFDColoring fd,const char prefix[],const char optionname[]) 410 { 411 PetscErrorCode ierr; 412 PetscBool flg; 413 PetscViewer viewer; 414 PetscViewerFormat format; 415 416 PetscFunctionBegin; 417 if (prefix) { 418 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)fd),((PetscObject)fd)->options,prefix,optionname,&viewer,&format,&flg);CHKERRQ(ierr); 419 } else { 420 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)fd),((PetscObject)fd)->options,((PetscObject)fd)->prefix,optionname,&viewer,&format,&flg);CHKERRQ(ierr); 421 } 422 if (flg) { 423 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 424 ierr = MatFDColoringView(fd,viewer);CHKERRQ(ierr); 425 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 426 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 427 } 428 PetscFunctionReturn(0); 429 } 430 431 /*@ 432 MatFDColoringCreate - Creates a matrix coloring context for finite difference 433 computation of Jacobians. 434 435 Collective on Mat 436 437 Input Parameters: 438 + mat - the matrix containing the nonzero structure of the Jacobian 439 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 440 441 Output Parameter: 442 . color - the new coloring context 443 444 Level: intermediate 445 446 .seealso: MatFDColoringDestroy(),SNESComputeJacobianDefaultColor(), ISColoringCreate(), 447 MatFDColoringSetFunction(), MatFDColoringSetFromOptions(), MatFDColoringApply(), 448 MatFDColoringView(), MatFDColoringSetParameters(), MatColoringCreate(), DMCreateColoring() 449 @*/ 450 PetscErrorCode MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color) 451 { 452 MatFDColoring c; 453 MPI_Comm comm; 454 PetscErrorCode ierr; 455 PetscInt M,N; 456 457 PetscFunctionBegin; 458 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 459 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 460 ierr = PetscLogEventBegin(MAT_FDColoringCreate,mat,0,0,0);CHKERRQ(ierr); 461 ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 462 if (M != N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Only for square matrices"); 463 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 464 ierr = PetscHeaderCreate(c,MAT_FDCOLORING_CLASSID,"MatFDColoring","Jacobian computation via finite differences with coloring","Mat",comm,MatFDColoringDestroy,MatFDColoringView);CHKERRQ(ierr); 465 466 c->ctype = iscoloring->ctype; 467 ierr = PetscObjectGetId((PetscObject)mat,&c->matid);CHKERRQ(ierr); 468 469 if (mat->ops->fdcoloringcreate) { 470 ierr = (*mat->ops->fdcoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 471 } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 472 473 ierr = MatCreateVecs(mat,NULL,&c->w1);CHKERRQ(ierr); 474 /* Vec is used instensively in particular piece of scalar CPU code; won't benifit from bouncing back and forth to the GPU */ 475 ierr = VecBindToCPU(c->w1,PETSC_TRUE);CHKERRQ(ierr); 476 ierr = PetscLogObjectParent((PetscObject)c,(PetscObject)c->w1);CHKERRQ(ierr); 477 ierr = VecDuplicate(c->w1,&c->w2);CHKERRQ(ierr); 478 /* Vec is used instensively in particular piece of scalar CPU code; won't benifit from bouncing back and forth to the GPU */ 479 ierr = VecBindToCPU(c->w2,PETSC_TRUE);CHKERRQ(ierr); 480 ierr = PetscLogObjectParent((PetscObject)c,(PetscObject)c->w2);CHKERRQ(ierr); 481 482 c->error_rel = PETSC_SQRT_MACHINE_EPSILON; 483 c->umin = 100.0*PETSC_SQRT_MACHINE_EPSILON; 484 c->currentcolor = -1; 485 c->htype = "wp"; 486 c->fset = PETSC_FALSE; 487 c->setupcalled = PETSC_FALSE; 488 489 *color = c; 490 ierr = PetscObjectCompose((PetscObject)mat,"SNESMatFDColoring",(PetscObject)c);CHKERRQ(ierr); 491 ierr = PetscLogEventEnd(MAT_FDColoringCreate,mat,0,0,0);CHKERRQ(ierr); 492 PetscFunctionReturn(0); 493 } 494 495 /*@ 496 MatFDColoringDestroy - Destroys a matrix coloring context that was created 497 via MatFDColoringCreate(). 498 499 Collective on MatFDColoring 500 501 Input Parameter: 502 . c - coloring context 503 504 Level: intermediate 505 506 .seealso: MatFDColoringCreate() 507 @*/ 508 PetscErrorCode MatFDColoringDestroy(MatFDColoring *c) 509 { 510 PetscErrorCode ierr; 511 PetscInt i; 512 MatFDColoring color = *c; 513 514 PetscFunctionBegin; 515 if (!*c) PetscFunctionReturn(0); 516 if (--((PetscObject)color)->refct > 0) {*c = 0; PetscFunctionReturn(0);} 517 518 /* we do not free the column arrays since their entries are owned by the ISs in color->isa */ 519 for (i=0; i<color->ncolors; i++) { 520 ierr = ISDestroy(&color->isa[i]);CHKERRQ(ierr); 521 } 522 ierr = PetscFree(color->isa);CHKERRQ(ierr); 523 ierr = PetscFree2(color->ncolumns,color->columns);CHKERRQ(ierr); 524 ierr = PetscFree(color->nrows);CHKERRQ(ierr); 525 if (color->htype[0] == 'w') { 526 ierr = PetscFree(color->matentry2);CHKERRQ(ierr); 527 } else { 528 ierr = PetscFree(color->matentry);CHKERRQ(ierr); 529 } 530 ierr = PetscFree(color->dy);CHKERRQ(ierr); 531 if (color->vscale) {ierr = VecDestroy(&color->vscale);CHKERRQ(ierr);} 532 ierr = VecDestroy(&color->w1);CHKERRQ(ierr); 533 ierr = VecDestroy(&color->w2);CHKERRQ(ierr); 534 ierr = VecDestroy(&color->w3);CHKERRQ(ierr); 535 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 536 PetscFunctionReturn(0); 537 } 538 539 /*@C 540 MatFDColoringGetPerturbedColumns - Returns the indices of the columns that 541 that are currently being perturbed. 542 543 Not Collective 544 545 Input Parameters: 546 . coloring - coloring context created with MatFDColoringCreate() 547 548 Output Parameters: 549 + n - the number of local columns being perturbed 550 - cols - the column indices, in global numbering 551 552 Level: advanced 553 554 Note: IF the matrix type is BAIJ, then the block column indices are returned 555 556 Fortran Note: 557 This routine has a different interface for Fortran 558 $ #include <petsc/finclude/petscmat.h> 559 $ use petscmat 560 $ PetscInt, pointer :: array(:) 561 $ PetscErrorCode ierr 562 $ MatFDColoring i 563 $ call MatFDColoringGetPerturbedColumnsF90(i,array,ierr) 564 $ use the entries of array ... 565 $ call MatFDColoringRestorePerturbedColumnsF90(i,array,ierr) 566 567 .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView(), MatFDColoringApply() 568 569 @*/ 570 PetscErrorCode MatFDColoringGetPerturbedColumns(MatFDColoring coloring,PetscInt *n,const PetscInt *cols[]) 571 { 572 PetscFunctionBegin; 573 if (coloring->currentcolor >= 0) { 574 *n = coloring->ncolumns[coloring->currentcolor]; 575 *cols = coloring->columns[coloring->currentcolor]; 576 } else { 577 *n = 0; 578 } 579 PetscFunctionReturn(0); 580 } 581 582 /*@ 583 MatFDColoringApply - Given a matrix for which a MatFDColoring context 584 has been created, computes the Jacobian for a function via finite differences. 585 586 Collective on MatFDColoring 587 588 Input Parameters: 589 + mat - location to store Jacobian 590 . coloring - coloring context created with MatFDColoringCreate() 591 . x1 - location at which Jacobian is to be computed 592 - sctx - context required by function, if this is being used with the SNES solver then it is SNES object, otherwise it is null 593 594 Options Database Keys: 595 + -mat_fd_type - "wp" or "ds" (see MATMFFD_WP or MATMFFD_DS) 596 . -mat_fd_coloring_view - Activates basic viewing or coloring 597 . -mat_fd_coloring_view draw - Activates drawing of coloring 598 - -mat_fd_coloring_view ::ascii_info - Activates viewing of coloring info 599 600 Level: intermediate 601 602 .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView(), MatFDColoringSetFunction() 603 604 @*/ 605 PetscErrorCode MatFDColoringApply(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 606 { 607 PetscErrorCode ierr; 608 PetscBool eq; 609 610 PetscFunctionBegin; 611 PetscValidHeaderSpecific(J,MAT_CLASSID,1); 612 PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_CLASSID,2); 613 PetscValidHeaderSpecific(x1,VEC_CLASSID,3); 614 ierr = PetscObjectCompareId((PetscObject)J,coloring->matid,&eq);CHKERRQ(ierr); 615 if (!eq) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_WRONG,"Matrix used with MatFDColoringApply() must be that used with MatFDColoringCreate()"); 616 if (!coloring->f) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetFunction()"); 617 if (!J->ops->fdcoloringapply) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)J)->type_name); 618 if (!coloring->setupcalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetUp()"); 619 620 ierr = MatSetUnfactored(J);CHKERRQ(ierr); 621 ierr = PetscLogEventBegin(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr); 622 ierr = (*J->ops->fdcoloringapply)(J,coloring,x1,sctx);CHKERRQ(ierr); 623 ierr = PetscLogEventEnd(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr); 624 if (!coloring->viewed) { 625 ierr = MatFDColoringViewFromOptions(coloring,NULL,"-mat_fd_coloring_view");CHKERRQ(ierr); 626 coloring->viewed = PETSC_TRUE; 627 } 628 PetscFunctionReturn(0); 629 } 630