1*e090d566SSatish Balay /*$Id: fdmatrix.c,v 1.60 2000/04/12 04:24:17 bsmith Exp balay $*/ 2bbf0e169SBarry Smith 3bbf0e169SBarry Smith /* 4639f9d9dSBarry Smith This is where the abstract matrix operations are defined that are 5639f9d9dSBarry Smith used for finite difference computations of Jacobians using coloring. 6bbf0e169SBarry Smith */ 7bbf0e169SBarry Smith 8bbf0e169SBarry Smith #include "petsc.h" 9*e090d566SSatish Balay #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 10bbf0e169SBarry Smith #include "src/vec/vecimpl.h" 11bbf0e169SBarry Smith 125615d1e5SSatish Balay #undef __FUNC__ 13b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringView_Draw" 14005c665bSBarry Smith static int MatFDColoringView_Draw(MatFDColoring fd,Viewer viewer) 15005c665bSBarry Smith { 16005c665bSBarry Smith int ierr,i,j,pause; 17005c665bSBarry Smith PetscTruth isnull; 18005c665bSBarry Smith Draw draw; 19329f5518SBarry Smith PetscReal xr,yr,xl,yl,h,w,x,y,xc,yc,scale = 0.0; 20005c665bSBarry Smith DrawButton button; 21005c665bSBarry Smith 223a40ed3dSBarry Smith PetscFunctionBegin; 2377ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 243a40ed3dSBarry Smith ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 252bdab257SBarry Smith ierr = DrawSynchronizedClear(draw);CHKERRQ(ierr); 26005c665bSBarry Smith 27005c665bSBarry Smith xr = fd->N; yr = fd->M; h = yr/10.0; w = xr/10.0; 28005c665bSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 29005c665bSBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 30005c665bSBarry Smith 31005c665bSBarry Smith /* loop over colors */ 32005c665bSBarry Smith for (i=0; i<fd->ncolors; i++) { 33005c665bSBarry Smith for (j=0; j<fd->nrows[i]; j++) { 34005c665bSBarry Smith y = fd->M - fd->rows[i][j] - fd->rstart; 35005c665bSBarry Smith x = fd->columnsforrow[i][j]; 365cd90555SBarry Smith ierr = DrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1);CHKERRQ(ierr); 37005c665bSBarry Smith } 38005c665bSBarry Smith } 392bdab257SBarry Smith ierr = DrawSynchronizedFlush(draw);CHKERRQ(ierr); 40005c665bSBarry Smith ierr = DrawGetPause(draw,&pause);CHKERRQ(ierr); 413a40ed3dSBarry Smith if (pause >= 0) { PetscSleep(pause); PetscFunctionReturn(0);} 425cd90555SBarry Smith ierr = DrawCheckResizedWindow(draw);CHKERRQ(ierr); 435cd90555SBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);CHKERRQ(ierr); 44005c665bSBarry Smith while (button != BUTTON_RIGHT) { 452bdab257SBarry Smith ierr = DrawSynchronizedClear(draw);CHKERRQ(ierr); 46005c665bSBarry Smith if (button == BUTTON_LEFT) scale = .5; 47005c665bSBarry Smith else if (button == BUTTON_CENTER) scale = 2.; 48005c665bSBarry Smith xl = scale*(xl + w - xc) + xc - w*scale; 49005c665bSBarry Smith xr = scale*(xr - w - xc) + xc + w*scale; 50005c665bSBarry Smith yl = scale*(yl + h - yc) + yc - h*scale; 51005c665bSBarry Smith yr = scale*(yr - h - yc) + yc + h*scale; 52005c665bSBarry Smith w *= scale; h *= scale; 53005c665bSBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 54005c665bSBarry Smith /* loop over colors */ 55005c665bSBarry Smith for (i=0; i<fd->ncolors; i++) { 56005c665bSBarry Smith for (j=0; j<fd->nrows[i]; j++) { 57005c665bSBarry Smith y = fd->M - fd->rows[i][j] - fd->rstart; 58005c665bSBarry Smith x = fd->columnsforrow[i][j]; 595cd90555SBarry Smith ierr = DrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1);CHKERRQ(ierr); 60005c665bSBarry Smith } 61005c665bSBarry Smith } 625cd90555SBarry Smith ierr = DrawCheckResizedWindow(draw);CHKERRQ(ierr); 635cd90555SBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);CHKERRQ(ierr); 64005c665bSBarry Smith } 65005c665bSBarry Smith 663a40ed3dSBarry Smith PetscFunctionReturn(0); 67005c665bSBarry Smith } 68005c665bSBarry Smith 69005c665bSBarry Smith #undef __FUNC__ 70b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringView" 71bbf0e169SBarry Smith /*@C 72639f9d9dSBarry Smith MatFDColoringView - Views a finite difference coloring context. 73bbf0e169SBarry Smith 744c49b128SBarry Smith Collective on MatFDColoring 75fee21e36SBarry Smith 76ef5ee4d1SLois Curfman McInnes Input Parameters: 77ef5ee4d1SLois Curfman McInnes + c - the coloring context 78ef5ee4d1SLois Curfman McInnes - viewer - visualization context 79ef5ee4d1SLois Curfman McInnes 8015091d37SBarry Smith Level: intermediate 8115091d37SBarry Smith 82b4fc646aSLois Curfman McInnes Notes: 83b4fc646aSLois Curfman McInnes The available visualization contexts include 84ef5ee4d1SLois Curfman McInnes + VIEWER_STDOUT_SELF - standard output (default) 85ef5ee4d1SLois Curfman McInnes . VIEWER_STDOUT_WORLD - synchronized standard 86ef5ee4d1SLois Curfman McInnes output where only the first processor opens 87ef5ee4d1SLois Curfman McInnes the file. All other processors send their 88ef5ee4d1SLois Curfman McInnes data to the first processor to print. 89c655490fSBarry Smith - VIEWER_DRAW_WORLD - graphical display of nonzero structure 90bbf0e169SBarry Smith 91639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 92005c665bSBarry Smith 93b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, view 94bbf0e169SBarry Smith @*/ 95b4fc646aSLois Curfman McInnes int MatFDColoringView(MatFDColoring c,Viewer viewer) 96bbf0e169SBarry Smith { 97639f9d9dSBarry Smith int i,j,format,ierr; 986831982aSBarry Smith PetscTruth isdraw,isascii; 99bbf0e169SBarry Smith 1003a40ed3dSBarry Smith PetscFunctionBegin; 101b4fc646aSLois Curfman McInnes PetscValidHeaderSpecific(c,MAT_FDCOLORING_COOKIE); 1023eda8832SBarry Smith if (!viewer) viewer = VIEWER_STDOUT_(c->comm); 1030f5bd95cSBarry Smith PetscValidHeaderSpecific(viewer,VIEWER_COOKIE); 1046831982aSBarry Smith PetscCheckSameComm(c,viewer); 105bbf0e169SBarry Smith 1066831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr); 1076831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr); 1080f5bd95cSBarry Smith if (isdraw) { 109b4fc646aSLois Curfman McInnes ierr = MatFDColoringView_Draw(c,viewer);CHKERRQ(ierr); 1100f5bd95cSBarry Smith } else if (isascii) { 111d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"MatFDColoring Object:\n");CHKERRQ(ierr); 112d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer," Error tolerance=%g\n",c->error_rel);CHKERRQ(ierr); 113d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer," Umin=%g\n",c->umin);CHKERRQ(ierr); 114d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer," Number of colors=%d\n",c->ncolors);CHKERRQ(ierr); 115ae09f205SBarry Smith 116ae09f205SBarry Smith ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 117ae09f205SBarry Smith if (format != VIEWER_FORMAT_ASCII_INFO) { 118b4fc646aSLois Curfman McInnes for (i=0; i<c->ncolors; i++) { 119d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer," Information for color %d\n",i);CHKERRQ(ierr); 120d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer," Number of columns %d\n",c->ncolumns[i]);CHKERRQ(ierr); 121b4fc646aSLois Curfman McInnes for (j=0; j<c->ncolumns[i]; j++) { 122d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d\n",c->columns[i][j]);CHKERRQ(ierr); 123639f9d9dSBarry Smith } 124d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer," Number of rows %d\n",c->nrows[i]);CHKERRQ(ierr); 125b4fc646aSLois Curfman McInnes for (j=0; j<c->nrows[i]; j++) { 126d132466eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %d \n",c->rows[i][j],c->columnsforrow[i][j]);CHKERRQ(ierr); 127b4fc646aSLois Curfman McInnes } 128bbf0e169SBarry Smith } 129bbf0e169SBarry Smith } 1306831982aSBarry Smith ierr = ViewerFlush(viewer);CHKERRQ(ierr); 1315cd90555SBarry Smith } else { 1320f5bd95cSBarry Smith SETERRQ1(1,1,"Viewer type %s not supported for MatFDColoring",((PetscObject)viewer)->type_name); 133bbf0e169SBarry Smith } 1343a40ed3dSBarry Smith PetscFunctionReturn(0); 135639f9d9dSBarry Smith } 136639f9d9dSBarry Smith 1375615d1e5SSatish Balay #undef __FUNC__ 138b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringSetParameters" 139639f9d9dSBarry Smith /*@ 140b4fc646aSLois Curfman McInnes MatFDColoringSetParameters - Sets the parameters for the sparse approximation of 141b4fc646aSLois Curfman McInnes a Jacobian matrix using finite differences. 142639f9d9dSBarry Smith 143ef5ee4d1SLois Curfman McInnes Collective on MatFDColoring 144ef5ee4d1SLois Curfman McInnes 145ef5ee4d1SLois Curfman McInnes The Jacobian is estimated with the differencing approximation 146ef5ee4d1SLois Curfman McInnes .vb 14765f2ba5bSLois Curfman McInnes F'(u)_{:,i} = [F(u+h*dx_{i}) - F(u)]/h where 148f23b5b22SLois Curfman McInnes h = error_rel*u[i] if abs(u[i]) > umin 149f23b5b22SLois Curfman McInnes = +/- error_rel*umin otherwise, with +/- determined by the sign of u[i] 150ef5ee4d1SLois Curfman McInnes dx_{i} = (0, ... 1, .... 0) 151ef5ee4d1SLois Curfman McInnes .ve 152639f9d9dSBarry Smith 153639f9d9dSBarry Smith Input Parameters: 154ef5ee4d1SLois Curfman McInnes + coloring - the coloring context 155639f9d9dSBarry Smith . error_rel - relative error 156f23b5b22SLois Curfman McInnes - umin - minimum allowable u-value magnitude 157fee21e36SBarry Smith 15815091d37SBarry Smith Level: advanced 15915091d37SBarry Smith 160b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, parameters 161b4fc646aSLois Curfman McInnes 162b4fc646aSLois Curfman McInnes .seealso: MatFDColoringCreate() 163639f9d9dSBarry Smith @*/ 164329f5518SBarry Smith int MatFDColoringSetParameters(MatFDColoring matfd,PetscReal error,PetscReal umin) 165639f9d9dSBarry Smith { 1663a40ed3dSBarry Smith PetscFunctionBegin; 167639f9d9dSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 168639f9d9dSBarry Smith 169639f9d9dSBarry Smith if (error != PETSC_DEFAULT) matfd->error_rel = error; 170639f9d9dSBarry Smith if (umin != PETSC_DEFAULT) matfd->umin = umin; 1713a40ed3dSBarry Smith PetscFunctionReturn(0); 172639f9d9dSBarry Smith } 173639f9d9dSBarry Smith 1745615d1e5SSatish Balay #undef __FUNC__ 175b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringSetFrequency" 176005c665bSBarry Smith /*@ 177e0907662SLois Curfman McInnes MatFDColoringSetFrequency - Sets the frequency for computing new Jacobian 178e0907662SLois Curfman McInnes matrices. 179005c665bSBarry Smith 180fee21e36SBarry Smith Collective on MatFDColoring 181fee21e36SBarry Smith 182ef5ee4d1SLois Curfman McInnes Input Parameters: 183ef5ee4d1SLois Curfman McInnes + coloring - the coloring context 184ef5ee4d1SLois Curfman McInnes - freq - frequency (default is 1) 185ef5ee4d1SLois Curfman McInnes 18615091d37SBarry Smith Options Database Keys: 18715091d37SBarry Smith . -mat_fd_coloring_freq <freq> - Sets coloring frequency 18815091d37SBarry Smith 18915091d37SBarry Smith Level: advanced 19015091d37SBarry Smith 191e0907662SLois Curfman McInnes Notes: 192e0907662SLois Curfman McInnes Using a modified Newton strategy, where the Jacobian remains fixed for several 193e0907662SLois Curfman McInnes iterations, can be cost effective in terms of overall nonlinear solution 194e0907662SLois Curfman McInnes efficiency. This parameter indicates that a new Jacobian will be computed every 195e0907662SLois Curfman McInnes <freq> nonlinear iterations. 196e0907662SLois Curfman McInnes 197b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, frequency 198ef5ee4d1SLois Curfman McInnes 199ef5ee4d1SLois Curfman McInnes .seealso: MatFDColoringCreate(), MatFDColoringGetFrequency() 200005c665bSBarry Smith @*/ 201005c665bSBarry Smith int MatFDColoringSetFrequency(MatFDColoring matfd,int freq) 202005c665bSBarry Smith { 2033a40ed3dSBarry Smith PetscFunctionBegin; 204005c665bSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 205005c665bSBarry Smith 206005c665bSBarry Smith matfd->freq = freq; 2073a40ed3dSBarry Smith PetscFunctionReturn(0); 208005c665bSBarry Smith } 209005c665bSBarry Smith 210005c665bSBarry Smith #undef __FUNC__ 211b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringGetFrequency" 212ff0cfa39SBarry Smith /*@ 213ff0cfa39SBarry Smith MatFDColoringGetFrequency - Gets the frequency for computing new Jacobian 214ff0cfa39SBarry Smith matrices. 215ff0cfa39SBarry Smith 216ef5ee4d1SLois Curfman McInnes Not Collective 217ef5ee4d1SLois Curfman McInnes 218ff0cfa39SBarry Smith Input Parameters: 219ff0cfa39SBarry Smith . coloring - the coloring context 220ff0cfa39SBarry Smith 221ff0cfa39SBarry Smith Output Parameters: 222ff0cfa39SBarry Smith . freq - frequency (default is 1) 223ff0cfa39SBarry Smith 22415091d37SBarry Smith Options Database Keys: 22515091d37SBarry Smith . -mat_fd_coloring_freq <freq> - Sets coloring frequency 22615091d37SBarry Smith 22715091d37SBarry Smith Level: advanced 22815091d37SBarry Smith 229ff0cfa39SBarry Smith Notes: 230ff0cfa39SBarry Smith Using a modified Newton strategy, where the Jacobian remains fixed for several 231ff0cfa39SBarry Smith iterations, can be cost effective in terms of overall nonlinear solution 232ff0cfa39SBarry Smith efficiency. This parameter indicates that a new Jacobian will be computed every 233ff0cfa39SBarry Smith <freq> nonlinear iterations. 234ff0cfa39SBarry Smith 235ff0cfa39SBarry Smith .keywords: Mat, finite differences, coloring, get, frequency 236ef5ee4d1SLois Curfman McInnes 237ef5ee4d1SLois Curfman McInnes .seealso: MatFDColoringSetFrequency() 238ff0cfa39SBarry Smith @*/ 239ff0cfa39SBarry Smith int MatFDColoringGetFrequency(MatFDColoring matfd,int *freq) 240ff0cfa39SBarry Smith { 2413a40ed3dSBarry Smith PetscFunctionBegin; 242ff0cfa39SBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 243ff0cfa39SBarry Smith 244ff0cfa39SBarry Smith *freq = matfd->freq; 2453a40ed3dSBarry Smith PetscFunctionReturn(0); 246ff0cfa39SBarry Smith } 247ff0cfa39SBarry Smith 248ff0cfa39SBarry Smith #undef __FUNC__ 249b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringSetFunction" 250d64ed03dSBarry Smith /*@C 251005c665bSBarry Smith MatFDColoringSetFunction - Sets the function to use for computing the Jacobian. 252005c665bSBarry Smith 253fee21e36SBarry Smith Collective on MatFDColoring 254fee21e36SBarry Smith 255ef5ee4d1SLois Curfman McInnes Input Parameters: 256ef5ee4d1SLois Curfman McInnes + coloring - the coloring context 257ef5ee4d1SLois Curfman McInnes . f - the function 258ef5ee4d1SLois Curfman McInnes - fctx - the optional user-defined function context 259ef5ee4d1SLois Curfman McInnes 26015091d37SBarry Smith Level: intermediate 26115091d37SBarry Smith 262f881d145SBarry Smith Notes: 263f881d145SBarry Smith In Fortran you must call MatFDColoringSetFunctionSNES() for a coloring object to 264f881d145SBarry Smith be used with the SNES solvers and MatFDColoringSetFunctionTS() if it is to be used 265f881d145SBarry Smith with the TS solvers. 266f881d145SBarry Smith 267b4fc646aSLois Curfman McInnes .keywords: Mat, Jacobian, finite differences, set, function 268005c665bSBarry Smith @*/ 269840b8ebdSBarry Smith int MatFDColoringSetFunction(MatFDColoring matfd,int (*f)(void),void *fctx) 270005c665bSBarry Smith { 2713a40ed3dSBarry Smith PetscFunctionBegin; 272005c665bSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 273005c665bSBarry Smith 274005c665bSBarry Smith matfd->f = f; 275005c665bSBarry Smith matfd->fctx = fctx; 276005c665bSBarry Smith 2773a40ed3dSBarry Smith PetscFunctionReturn(0); 278005c665bSBarry Smith } 279005c665bSBarry Smith 280005c665bSBarry Smith #undef __FUNC__ 281b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringSetFromOptions" 282639f9d9dSBarry Smith /*@ 283b4fc646aSLois Curfman McInnes MatFDColoringSetFromOptions - Sets coloring finite difference parameters from 284639f9d9dSBarry Smith the options database. 285639f9d9dSBarry Smith 286fee21e36SBarry Smith Collective on MatFDColoring 287fee21e36SBarry Smith 28865f2ba5bSLois Curfman McInnes The Jacobian, F'(u), is estimated with the differencing approximation 289ef5ee4d1SLois Curfman McInnes .vb 29065f2ba5bSLois Curfman McInnes F'(u)_{:,i} = [F(u+h*dx_{i}) - F(u)]/h where 291f23b5b22SLois Curfman McInnes h = error_rel*u[i] if abs(u[i]) > umin 292f23b5b22SLois Curfman McInnes = +/- error_rel*umin otherwise, with +/- determined by the sign of u[i] 293ef5ee4d1SLois Curfman McInnes dx_{i} = (0, ... 1, .... 0) 294ef5ee4d1SLois Curfman McInnes .ve 295ef5ee4d1SLois Curfman McInnes 296ef5ee4d1SLois Curfman McInnes Input Parameter: 297ef5ee4d1SLois Curfman McInnes . coloring - the coloring context 298ef5ee4d1SLois Curfman McInnes 299b4fc646aSLois Curfman McInnes Options Database Keys: 300ef5ee4d1SLois Curfman McInnes + -mat_fd_coloring_error <err> - Sets <err> (square root 301ef5ee4d1SLois Curfman McInnes of relative error in the function) 302f23b5b22SLois Curfman McInnes . -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude 303ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_freq <freq> - Sets frequency of computing a new Jacobian 304ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_view - Activates basic viewing 305ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_view_info - Activates viewing info 306ef5ee4d1SLois Curfman McInnes - -mat_fd_coloring_view_draw - Activates drawing 307639f9d9dSBarry Smith 30815091d37SBarry Smith Level: intermediate 30915091d37SBarry Smith 310b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, parameters 311639f9d9dSBarry Smith @*/ 312639f9d9dSBarry Smith int MatFDColoringSetFromOptions(MatFDColoring matfd) 313639f9d9dSBarry Smith { 314f1af5d2fSBarry Smith int ierr,freq = 1; 315329f5518SBarry Smith PetscReal error = PETSC_DEFAULT,umin = PETSC_DEFAULT; 316f1af5d2fSBarry Smith PetscTruth flag; 3173a40ed3dSBarry Smith 3183a40ed3dSBarry Smith PetscFunctionBegin; 319639f9d9dSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 320639f9d9dSBarry Smith 321f1af5d2fSBarry Smith ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_err",&error,PETSC_NULL);CHKERRQ(ierr); 322f1af5d2fSBarry Smith ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_umin",&umin,PETSC_NULL);CHKERRQ(ierr); 323639f9d9dSBarry Smith ierr = MatFDColoringSetParameters(matfd,error,umin);CHKERRQ(ierr); 324f1af5d2fSBarry Smith ierr = OptionsGetInt(matfd->prefix,"-mat_fd_coloring_freq",&freq,PETSC_NULL);CHKERRQ(ierr); 325005c665bSBarry Smith ierr = MatFDColoringSetFrequency(matfd,freq);CHKERRQ(ierr); 326005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help",&flag);CHKERRQ(ierr); 327639f9d9dSBarry Smith if (flag) { 328639f9d9dSBarry Smith ierr = MatFDColoringPrintHelp(matfd);CHKERRQ(ierr); 329639f9d9dSBarry Smith } 3303a40ed3dSBarry Smith PetscFunctionReturn(0); 331639f9d9dSBarry Smith } 332639f9d9dSBarry Smith 3335615d1e5SSatish Balay #undef __FUNC__ 334b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringPrintHelp" 335639f9d9dSBarry Smith /*@ 336639f9d9dSBarry Smith MatFDColoringPrintHelp - Prints help message for matrix finite difference calculations 337639f9d9dSBarry Smith using coloring. 338639f9d9dSBarry Smith 339ef5ee4d1SLois Curfman McInnes Collective on MatFDColoring 340ef5ee4d1SLois Curfman McInnes 341639f9d9dSBarry Smith Input Parameter: 342639f9d9dSBarry Smith . fdcoloring - the MatFDColoring context 343639f9d9dSBarry Smith 34415091d37SBarry Smith Level: intermediate 34515091d37SBarry Smith 346639f9d9dSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringSetFromOptions() 347639f9d9dSBarry Smith @*/ 348639f9d9dSBarry Smith int MatFDColoringPrintHelp(MatFDColoring fd) 349639f9d9dSBarry Smith { 350d132466eSBarry Smith int ierr; 351d132466eSBarry Smith 3523a40ed3dSBarry Smith PetscFunctionBegin; 353639f9d9dSBarry Smith PetscValidHeaderSpecific(fd,MAT_FDCOLORING_COOKIE); 354639f9d9dSBarry Smith 355d132466eSBarry Smith ierr = (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_err <err>: set sqrt rel tol in function, defaults to %g\n",fd->error_rel);CHKERRQ(ierr); 356d132466eSBarry Smith ierr = (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_umin <umin>: see users manual, defaults to %d\n",fd->umin);CHKERRQ(ierr); 357d132466eSBarry Smith ierr = (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_freq <freq>: frequency that Jacobian is recomputed, defaults to %d\n",fd->freq);CHKERRQ(ierr); 358d132466eSBarry Smith ierr = (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view\n");CHKERRQ(ierr); 359d132466eSBarry Smith ierr = (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view_draw\n");CHKERRQ(ierr); 360d132466eSBarry Smith ierr = (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view_info\n");CHKERRQ(ierr); 3613a40ed3dSBarry Smith PetscFunctionReturn(0); 362005c665bSBarry Smith } 363005c665bSBarry Smith 364433994e6SBarry Smith #undef __FUNC__ 365b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringView_Private" 366005c665bSBarry Smith int MatFDColoringView_Private(MatFDColoring fd) 367005c665bSBarry Smith { 368f1af5d2fSBarry Smith int ierr; 369f1af5d2fSBarry Smith PetscTruth flg; 370005c665bSBarry Smith 3713a40ed3dSBarry Smith PetscFunctionBegin; 372005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view",&flg);CHKERRQ(ierr); 373005c665bSBarry Smith if (flg) { 374f8590f6eSBarry Smith ierr = MatFDColoringView(fd,VIEWER_STDOUT_(fd->comm));CHKERRQ(ierr); 375005c665bSBarry Smith } 376ae09f205SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view_info",&flg);CHKERRQ(ierr); 377ae09f205SBarry Smith if (flg) { 378f8590f6eSBarry Smith ierr = ViewerPushFormat(VIEWER_STDOUT_(fd->comm),VIEWER_FORMAT_ASCII_INFO,PETSC_NULL);CHKERRQ(ierr); 379f8590f6eSBarry Smith ierr = MatFDColoringView(fd,VIEWER_STDOUT_(fd->comm));CHKERRQ(ierr); 380f8590f6eSBarry Smith ierr = ViewerPopFormat(VIEWER_STDOUT_(fd->comm));CHKERRQ(ierr); 381ae09f205SBarry Smith } 382005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view_draw",&flg);CHKERRQ(ierr); 383005c665bSBarry Smith if (flg) { 384c655490fSBarry Smith ierr = MatFDColoringView(fd,VIEWER_DRAW_(fd->comm));CHKERRQ(ierr); 385c655490fSBarry Smith ierr = ViewerFlush(VIEWER_DRAW_(fd->comm));CHKERRQ(ierr); 386005c665bSBarry Smith } 3873a40ed3dSBarry Smith PetscFunctionReturn(0); 388bbf0e169SBarry Smith } 389bbf0e169SBarry Smith 3905615d1e5SSatish Balay #undef __FUNC__ 391b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringCreate" 392bbf0e169SBarry Smith /*@C 393639f9d9dSBarry Smith MatFDColoringCreate - Creates a matrix coloring context for finite difference 394639f9d9dSBarry Smith computation of Jacobians. 395bbf0e169SBarry Smith 396ef5ee4d1SLois Curfman McInnes Collective on Mat 397ef5ee4d1SLois Curfman McInnes 398639f9d9dSBarry Smith Input Parameters: 399ef5ee4d1SLois Curfman McInnes + mat - the matrix containing the nonzero structure of the Jacobian 400ef5ee4d1SLois Curfman McInnes - iscoloring - the coloring of the matrix 401bbf0e169SBarry Smith 402bbf0e169SBarry Smith Output Parameter: 403639f9d9dSBarry Smith . color - the new coloring context 404bbf0e169SBarry Smith 405b4fc646aSLois Curfman McInnes Options Database Keys: 406ef5ee4d1SLois Curfman McInnes + -mat_fd_coloring_view - Activates basic viewing or coloring 407ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_view_draw - Activates drawing of coloring 408ef5ee4d1SLois Curfman McInnes - -mat_fd_coloring_view_info - Activates viewing of coloring info 409639f9d9dSBarry Smith 41015091d37SBarry Smith Level: intermediate 41115091d37SBarry Smith 4126831982aSBarry Smith .seealso: MatFDColoringDestroy(),SNESDefaultComputeJacobianColor(), ISColoringCreate(), 4136831982aSBarry Smith MatFDColoringSetFunction(), MatFDColoringSetFromOptions() 414bbf0e169SBarry Smith @*/ 415639f9d9dSBarry Smith int MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color) 416bbf0e169SBarry Smith { 417639f9d9dSBarry Smith MatFDColoring c; 418639f9d9dSBarry Smith MPI_Comm comm; 419639f9d9dSBarry Smith int ierr,M,N; 420639f9d9dSBarry Smith 4213a40ed3dSBarry Smith PetscFunctionBegin; 422639f9d9dSBarry Smith ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 423e3372554SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Only for square matrices"); 424639f9d9dSBarry Smith 425f881d145SBarry Smith ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4263f1db9ecSBarry Smith PetscHeaderCreate(c,_p_MatFDColoring,int,MAT_FDCOLORING_COOKIE,0,"MatFDColoring",comm, 4273f1db9ecSBarry Smith MatFDColoringDestroy,MatFDColoringView); 428639f9d9dSBarry Smith PLogObjectCreate(c); 429639f9d9dSBarry Smith 430f830108cSBarry Smith if (mat->ops->fdcoloringcreate) { 431f830108cSBarry Smith ierr = (*mat->ops->fdcoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 432639f9d9dSBarry Smith } else { 433e3372554SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Code not yet written for this matrix type"); 434639f9d9dSBarry Smith } 435639f9d9dSBarry Smith 436639f9d9dSBarry Smith c->error_rel = 1.e-8; 437ae09f205SBarry Smith c->umin = 1.e-6; 438005c665bSBarry Smith c->freq = 1; 439005c665bSBarry Smith 440005c665bSBarry Smith ierr = MatFDColoringView_Private(c);CHKERRQ(ierr); 441639f9d9dSBarry Smith 442639f9d9dSBarry Smith *color = c; 443639f9d9dSBarry Smith 4443a40ed3dSBarry Smith PetscFunctionReturn(0); 445bbf0e169SBarry Smith } 446bbf0e169SBarry Smith 4475615d1e5SSatish Balay #undef __FUNC__ 448b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringDestroy" 449bbf0e169SBarry Smith /*@C 450639f9d9dSBarry Smith MatFDColoringDestroy - Destroys a matrix coloring context that was created 451639f9d9dSBarry Smith via MatFDColoringCreate(). 452bbf0e169SBarry Smith 453ef5ee4d1SLois Curfman McInnes Collective on MatFDColoring 454ef5ee4d1SLois Curfman McInnes 455b4fc646aSLois Curfman McInnes Input Parameter: 456639f9d9dSBarry Smith . c - coloring context 457bbf0e169SBarry Smith 45815091d37SBarry Smith Level: intermediate 45915091d37SBarry Smith 460639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 461bbf0e169SBarry Smith @*/ 462639f9d9dSBarry Smith int MatFDColoringDestroy(MatFDColoring c) 463bbf0e169SBarry Smith { 464263760aaSBarry Smith int i,ierr; 465bbf0e169SBarry Smith 4663a40ed3dSBarry Smith PetscFunctionBegin; 4673a40ed3dSBarry Smith if (--c->refct > 0) PetscFunctionReturn(0); 468d4bb536fSBarry Smith 469639f9d9dSBarry Smith 470639f9d9dSBarry Smith for (i=0; i<c->ncolors; i++) { 471606d414cSSatish Balay if (c->columns[i]) {ierr = PetscFree(c->columns[i]);CHKERRQ(ierr);} 472606d414cSSatish Balay if (c->rows[i]) {ierr = PetscFree(c->rows[i]);CHKERRQ(ierr);} 473606d414cSSatish Balay if (c->columnsforrow[i]) {ierr = PetscFree(c->columnsforrow[i]);CHKERRQ(ierr);} 474bbf0e169SBarry Smith } 475606d414cSSatish Balay ierr = PetscFree(c->ncolumns);CHKERRQ(ierr); 476606d414cSSatish Balay ierr = PetscFree(c->columns);CHKERRQ(ierr); 477606d414cSSatish Balay ierr = PetscFree(c->nrows);CHKERRQ(ierr); 478606d414cSSatish Balay ierr = PetscFree(c->rows);CHKERRQ(ierr); 479606d414cSSatish Balay ierr = PetscFree(c->columnsforrow);CHKERRQ(ierr); 480606d414cSSatish Balay ierr = PetscFree(c->scale);CHKERRQ(ierr); 481005c665bSBarry Smith if (c->w1) { 482005c665bSBarry Smith ierr = VecDestroy(c->w1);CHKERRQ(ierr); 483005c665bSBarry Smith ierr = VecDestroy(c->w2);CHKERRQ(ierr); 484005c665bSBarry Smith ierr = VecDestroy(c->w3);CHKERRQ(ierr); 485005c665bSBarry Smith } 486639f9d9dSBarry Smith PLogObjectDestroy(c); 487639f9d9dSBarry Smith PetscHeaderDestroy(c); 4883a40ed3dSBarry Smith PetscFunctionReturn(0); 489bbf0e169SBarry Smith } 49043a90d84SBarry Smith 491005c665bSBarry Smith 4925615d1e5SSatish Balay #undef __FUNC__ 493b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringApply" 49443a90d84SBarry Smith /*@ 495e0907662SLois Curfman McInnes MatFDColoringApply - Given a matrix for which a MatFDColoring context 496e0907662SLois Curfman McInnes has been created, computes the Jacobian for a function via finite differences. 49743a90d84SBarry Smith 498fee21e36SBarry Smith Collective on MatFDColoring 499fee21e36SBarry Smith 500ef5ee4d1SLois Curfman McInnes Input Parameters: 501ef5ee4d1SLois Curfman McInnes + mat - location to store Jacobian 502ef5ee4d1SLois Curfman McInnes . coloring - coloring context created with MatFDColoringCreate() 503ef5ee4d1SLois Curfman McInnes . x1 - location at which Jacobian is to be computed 504ef5ee4d1SLois Curfman McInnes - sctx - optional context required by function (actually a SNES context) 505ef5ee4d1SLois Curfman McInnes 5068bba8e72SBarry Smith Options Database Keys: 507ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_freq <freq> - Sets coloring frequency 5088bba8e72SBarry Smith 50915091d37SBarry Smith Level: intermediate 51015091d37SBarry Smith 51143a90d84SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView() 51243a90d84SBarry Smith 51343a90d84SBarry Smith .keywords: coloring, Jacobian, finite differences 51443a90d84SBarry Smith @*/ 515005c665bSBarry Smith int MatFDColoringApply(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 51643a90d84SBarry Smith { 517f1af5d2fSBarry Smith int k,ierr,N,start,end,l,row,col,srow; 51843a90d84SBarry Smith Scalar dx,mone = -1.0,*y,*scale = coloring->scale,*xx,*wscale = coloring->wscale; 519329f5518SBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 52043a90d84SBarry Smith MPI_Comm comm = coloring->comm; 521005c665bSBarry Smith Vec w1,w2,w3; 522840b8ebdSBarry Smith int (*f)(void *,Vec,Vec,void*)= (int (*)(void *,Vec,Vec,void *))coloring->f; 523005c665bSBarry Smith void *fctx = coloring->fctx; 524f1af5d2fSBarry Smith PetscTruth flg; 525005c665bSBarry Smith 5263a40ed3dSBarry Smith PetscFunctionBegin; 527e0907662SLois Curfman McInnes PetscValidHeaderSpecific(J,MAT_COOKIE); 528e0907662SLois Curfman McInnes PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_COOKIE); 529e0907662SLois Curfman McInnes PetscValidHeaderSpecific(x1,VEC_COOKIE); 530e0907662SLois Curfman McInnes 531005c665bSBarry Smith 532005c665bSBarry Smith if (!coloring->w1) { 533005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 534005c665bSBarry Smith PLogObjectParent(coloring,coloring->w1); 535005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 536005c665bSBarry Smith PLogObjectParent(coloring,coloring->w2); 537005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 538005c665bSBarry Smith PLogObjectParent(coloring,coloring->w3); 539005c665bSBarry Smith } 540005c665bSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 54143a90d84SBarry Smith 5424c49b128SBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 543f1af5d2fSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 544f1af5d2fSBarry Smith if (flg) { 545e0907662SLois Curfman McInnes PLogInfo(coloring,"MatFDColoringApply: Not calling MatZeroEntries()\n"); 546e0907662SLois Curfman McInnes } else { 54743a90d84SBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 548e0907662SLois Curfman McInnes } 54943a90d84SBarry Smith 55043a90d84SBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 55143a90d84SBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 55243a90d84SBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 55343a90d84SBarry Smith 554549d3d68SSatish Balay ierr = PetscMemzero(wscale,N*sizeof(Scalar));CHKERRQ(ierr); 55543a90d84SBarry Smith /* 55643a90d84SBarry Smith Loop over each color 55743a90d84SBarry Smith */ 55843a90d84SBarry Smith 5593b28642cSBarry Smith ierr = VecGetArray(x1,&xx);CHKERRQ(ierr); 56043a90d84SBarry Smith for (k=0; k<coloring->ncolors; k++) { 56143a90d84SBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 56243a90d84SBarry Smith /* 56343a90d84SBarry Smith Loop over each column associated with color adding the 56443a90d84SBarry Smith perturbation to the vector w3. 56543a90d84SBarry Smith */ 56643a90d84SBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 56743a90d84SBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 56843a90d84SBarry Smith dx = xx[col-start]; 569ae09f205SBarry Smith if (dx == 0.0) dx = 1.0; 570aa482453SBarry Smith #if !defined(PETSC_USE_COMPLEX) 571ae09f205SBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 572ae09f205SBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 57343a90d84SBarry Smith #else 574329f5518SBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 575329f5518SBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 57643a90d84SBarry Smith #endif 57743a90d84SBarry Smith dx *= epsilon; 57843a90d84SBarry Smith wscale[col] = 1.0/dx; 5793b28642cSBarry Smith ierr = VecSetValues(w3,1,&col,&dx,ADD_VALUES);CHKERRQ(ierr); 58043a90d84SBarry Smith } 5813b28642cSBarry Smith 58243a90d84SBarry Smith /* 583e0907662SLois Curfman McInnes Evaluate function at x1 + dx (here dx is a vector of perturbations) 58443a90d84SBarry Smith */ 58543a90d84SBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 58643a90d84SBarry Smith ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr); 58743a90d84SBarry Smith /* Communicate scale to all processors */ 5886831982aSBarry Smith ierr = MPI_Allreduce(wscale,scale,N,MPIU_SCALAR,PetscSum_Op,comm);CHKERRQ(ierr); 58943a90d84SBarry Smith /* 590e0907662SLois Curfman McInnes Loop over rows of vector, putting results into Jacobian matrix 59143a90d84SBarry Smith */ 5923b28642cSBarry Smith ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 59343a90d84SBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 59443a90d84SBarry Smith row = coloring->rows[k][l]; 59543a90d84SBarry Smith col = coloring->columnsforrow[k][l]; 59643a90d84SBarry Smith y[row] *= scale[col]; 59743a90d84SBarry Smith srow = row + start; 59843a90d84SBarry Smith ierr = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 59943a90d84SBarry Smith } 6003b28642cSBarry Smith ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 60143a90d84SBarry Smith } 6023b28642cSBarry Smith ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 60343a90d84SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 60443a90d84SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6053a40ed3dSBarry Smith PetscFunctionReturn(0); 60643a90d84SBarry Smith } 607840b8ebdSBarry Smith 608840b8ebdSBarry Smith #undef __FUNC__ 609b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringApplyTS" 610840b8ebdSBarry Smith /*@ 611840b8ebdSBarry Smith MatFDColoringApplyTS - Given a matrix for which a MatFDColoring context 612840b8ebdSBarry Smith has been created, computes the Jacobian for a function via finite differences. 613840b8ebdSBarry Smith 614fee21e36SBarry Smith Collective on Mat, MatFDColoring, and Vec 615fee21e36SBarry Smith 616ef5ee4d1SLois Curfman McInnes Input Parameters: 6173b28642cSBarry Smith + mat - location to store Jacobian 618ef5ee4d1SLois Curfman McInnes . coloring - coloring context created with MatFDColoringCreate() 619ef5ee4d1SLois Curfman McInnes . x1 - location at which Jacobian is to be computed 620ef5ee4d1SLois Curfman McInnes - sctx - optional context required by function (actually a SNES context) 621ef5ee4d1SLois Curfman McInnes 622840b8ebdSBarry Smith Options Database Keys: 623ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_freq <freq> - Sets coloring frequency 624840b8ebdSBarry Smith 62515091d37SBarry Smith Level: intermediate 62615091d37SBarry Smith 627840b8ebdSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView() 628840b8ebdSBarry Smith 629840b8ebdSBarry Smith .keywords: coloring, Jacobian, finite differences 630840b8ebdSBarry Smith @*/ 631329f5518SBarry Smith int MatFDColoringApplyTS(Mat J,MatFDColoring coloring,PetscReal t,Vec x1,MatStructure *flag,void *sctx) 632840b8ebdSBarry Smith { 633f1af5d2fSBarry Smith int k,ierr,N,start,end,l,row,col,srow; 634329f5518SBarry Smith int (*f)(void *,PetscReal,Vec,Vec,void*)= (int (*)(void *,PetscReal,Vec,Vec,void *))coloring->f; 635840b8ebdSBarry Smith Scalar dx,mone = -1.0,*y,*scale = coloring->scale,*xx,*wscale = coloring->wscale; 636329f5518SBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 637840b8ebdSBarry Smith MPI_Comm comm = coloring->comm; 638840b8ebdSBarry Smith Vec w1,w2,w3; 639840b8ebdSBarry Smith void *fctx = coloring->fctx; 640f1af5d2fSBarry Smith PetscTruth flg; 641840b8ebdSBarry Smith 6423a40ed3dSBarry Smith PetscFunctionBegin; 643840b8ebdSBarry Smith PetscValidHeaderSpecific(J,MAT_COOKIE); 644840b8ebdSBarry Smith PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_COOKIE); 645840b8ebdSBarry Smith PetscValidHeaderSpecific(x1,VEC_COOKIE); 646840b8ebdSBarry Smith 647840b8ebdSBarry Smith if (!coloring->w1) { 648840b8ebdSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 649840b8ebdSBarry Smith PLogObjectParent(coloring,coloring->w1); 650840b8ebdSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 651840b8ebdSBarry Smith PLogObjectParent(coloring,coloring->w2); 652840b8ebdSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 653840b8ebdSBarry Smith PLogObjectParent(coloring,coloring->w3); 654840b8ebdSBarry Smith } 655840b8ebdSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 656840b8ebdSBarry Smith 657f1af5d2fSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 658f1af5d2fSBarry Smith if (flg) { 659840b8ebdSBarry Smith PLogInfo(coloring,"MatFDColoringApplyTS: Not calling MatZeroEntries()\n"); 660840b8ebdSBarry Smith } else { 661840b8ebdSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 662840b8ebdSBarry Smith } 663840b8ebdSBarry Smith 664840b8ebdSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 665840b8ebdSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 666840b8ebdSBarry Smith ierr = (*f)(sctx,t,x1,w1,fctx);CHKERRQ(ierr); 667840b8ebdSBarry Smith 668549d3d68SSatish Balay ierr = PetscMemzero(wscale,N*sizeof(Scalar));CHKERRQ(ierr); 669840b8ebdSBarry Smith /* 670840b8ebdSBarry Smith Loop over each color 671840b8ebdSBarry Smith */ 672840b8ebdSBarry Smith 6733b28642cSBarry Smith ierr = VecGetArray(x1,&xx);CHKERRQ(ierr); 674840b8ebdSBarry Smith for (k=0; k<coloring->ncolors; k++) { 675840b8ebdSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 676840b8ebdSBarry Smith /* 677840b8ebdSBarry Smith Loop over each column associated with color adding the 678840b8ebdSBarry Smith perturbation to the vector w3. 679840b8ebdSBarry Smith */ 680840b8ebdSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 681840b8ebdSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 682840b8ebdSBarry Smith dx = xx[col-start]; 683840b8ebdSBarry Smith if (dx == 0.0) dx = 1.0; 684aa482453SBarry Smith #if !defined(PETSC_USE_COMPLEX) 685840b8ebdSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 686840b8ebdSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 687840b8ebdSBarry Smith #else 688329f5518SBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 689329f5518SBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 690840b8ebdSBarry Smith #endif 691840b8ebdSBarry Smith dx *= epsilon; 692840b8ebdSBarry Smith wscale[col] = 1.0/dx; 6933b28642cSBarry Smith ierr = VecSetValues(w3,1,&col,&dx,ADD_VALUES);CHKERRQ(ierr); 694840b8ebdSBarry Smith } 695840b8ebdSBarry Smith /* 696840b8ebdSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 697840b8ebdSBarry Smith */ 698840b8ebdSBarry Smith ierr = (*f)(sctx,t,w3,w2,fctx);CHKERRQ(ierr); 699840b8ebdSBarry Smith ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr); 700840b8ebdSBarry Smith /* Communicate scale to all processors */ 7016831982aSBarry Smith ierr = MPI_Allreduce(wscale,scale,N,MPIU_SCALAR,PetscSum_Op,comm);CHKERRQ(ierr); 702840b8ebdSBarry Smith /* 703840b8ebdSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 704840b8ebdSBarry Smith */ 7053b28642cSBarry Smith ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 706840b8ebdSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 707840b8ebdSBarry Smith row = coloring->rows[k][l]; 708840b8ebdSBarry Smith col = coloring->columnsforrow[k][l]; 709840b8ebdSBarry Smith y[row] *= scale[col]; 710840b8ebdSBarry Smith srow = row + start; 711840b8ebdSBarry Smith ierr = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 712840b8ebdSBarry Smith } 7133b28642cSBarry Smith ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 714840b8ebdSBarry Smith } 7153b28642cSBarry Smith ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 716840b8ebdSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 717840b8ebdSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7183a40ed3dSBarry Smith PetscFunctionReturn(0); 719840b8ebdSBarry Smith } 7203b28642cSBarry Smith 7213b28642cSBarry Smith 7223b28642cSBarry Smith 723