1840b8ebdSBarry Smith 2a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 3*c655490fSBarry Smith static char vcid[] = "$Id: fdmatrix.c,v 1.40 1998/12/21 00:59:47 bsmith Exp bsmith $"; 4bbf0e169SBarry Smith #endif 5bbf0e169SBarry Smith 6bbf0e169SBarry Smith /* 7639f9d9dSBarry Smith This is where the abstract matrix operations are defined that are 8639f9d9dSBarry Smith used for finite difference computations of Jacobians using coloring. 9bbf0e169SBarry Smith */ 10bbf0e169SBarry Smith 11bbf0e169SBarry Smith #include "petsc.h" 12bbf0e169SBarry Smith #include "src/mat/matimpl.h" /*I "mat.h" I*/ 13bbf0e169SBarry Smith #include "src/vec/vecimpl.h" 14bbf0e169SBarry Smith 155615d1e5SSatish Balay #undef __FUNC__ 16d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringView_Draw" 17005c665bSBarry Smith static int MatFDColoringView_Draw(MatFDColoring fd,Viewer viewer) 18005c665bSBarry Smith { 19005c665bSBarry Smith int ierr,i,j,pause; 20005c665bSBarry Smith PetscTruth isnull; 21005c665bSBarry Smith Draw draw; 22d4bb536fSBarry Smith double xr,yr,xl,yl,h,w,x,y,xc,yc,scale = 0.0; 23005c665bSBarry Smith DrawButton button; 24005c665bSBarry Smith 253a40ed3dSBarry Smith PetscFunctionBegin; 2677ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw); CHKERRQ(ierr); 273a40ed3dSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 282bdab257SBarry Smith ierr = DrawSynchronizedClear(draw); CHKERRQ(ierr); 29005c665bSBarry Smith 30005c665bSBarry Smith xr = fd->N; yr = fd->M; h = yr/10.0; w = xr/10.0; 31005c665bSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 32005c665bSBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 33005c665bSBarry Smith 34005c665bSBarry Smith /* loop over colors */ 35005c665bSBarry Smith for (i=0; i<fd->ncolors; i++ ) { 36005c665bSBarry Smith for ( j=0; j<fd->nrows[i]; j++ ) { 37005c665bSBarry Smith y = fd->M - fd->rows[i][j] - fd->rstart; 38005c665bSBarry Smith x = fd->columnsforrow[i][j]; 395cd90555SBarry Smith ierr = DrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1); CHKERRQ(ierr); 40005c665bSBarry Smith } 41005c665bSBarry Smith } 422bdab257SBarry Smith ierr = DrawSynchronizedFlush(draw); CHKERRQ(ierr); 43005c665bSBarry Smith ierr = DrawGetPause(draw,&pause); CHKERRQ(ierr); 443a40ed3dSBarry Smith if (pause >= 0) { PetscSleep(pause); PetscFunctionReturn(0);} 455cd90555SBarry Smith ierr = DrawCheckResizedWindow(draw); CHKERRQ(ierr); 465cd90555SBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0); CHKERRQ(ierr); 47005c665bSBarry Smith while (button != BUTTON_RIGHT) { 482bdab257SBarry Smith ierr = DrawSynchronizedClear(draw); CHKERRQ(ierr); 49005c665bSBarry Smith if (button == BUTTON_LEFT) scale = .5; 50005c665bSBarry Smith else if (button == BUTTON_CENTER) scale = 2.; 51005c665bSBarry Smith xl = scale*(xl + w - xc) + xc - w*scale; 52005c665bSBarry Smith xr = scale*(xr - w - xc) + xc + w*scale; 53005c665bSBarry Smith yl = scale*(yl + h - yc) + yc - h*scale; 54005c665bSBarry Smith yr = scale*(yr - h - yc) + yc + h*scale; 55005c665bSBarry Smith w *= scale; h *= scale; 56005c665bSBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 57005c665bSBarry Smith /* loop over colors */ 58005c665bSBarry Smith for (i=0; i<fd->ncolors; i++ ) { 59005c665bSBarry Smith for ( j=0; j<fd->nrows[i]; j++ ) { 60005c665bSBarry Smith y = fd->M - fd->rows[i][j] - fd->rstart; 61005c665bSBarry Smith x = fd->columnsforrow[i][j]; 625cd90555SBarry Smith ierr = DrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1); CHKERRQ(ierr); 63005c665bSBarry Smith } 64005c665bSBarry Smith } 655cd90555SBarry Smith ierr = DrawCheckResizedWindow(draw); CHKERRQ(ierr); 665cd90555SBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0); CHKERRQ(ierr); 67005c665bSBarry Smith } 68005c665bSBarry Smith 693a40ed3dSBarry Smith PetscFunctionReturn(0); 70005c665bSBarry Smith } 71005c665bSBarry Smith 72005c665bSBarry Smith #undef __FUNC__ 73d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringView" 74bbf0e169SBarry Smith /*@C 75639f9d9dSBarry Smith MatFDColoringView - Views a finite difference coloring context. 76bbf0e169SBarry Smith 77fee21e36SBarry Smith Collective on MatFDColoring unless Viewer is VIEWER_STDOUT_SELF 78fee21e36SBarry Smith 79ef5ee4d1SLois Curfman McInnes Input Parameters: 80ef5ee4d1SLois Curfman McInnes + c - the coloring context 81ef5ee4d1SLois Curfman McInnes - viewer - visualization context 82ef5ee4d1SLois Curfman McInnes 83b4fc646aSLois Curfman McInnes Notes: 84b4fc646aSLois Curfman McInnes The available visualization contexts include 85ef5ee4d1SLois Curfman McInnes + VIEWER_STDOUT_SELF - standard output (default) 86ef5ee4d1SLois Curfman McInnes . VIEWER_STDOUT_WORLD - synchronized standard 87ef5ee4d1SLois Curfman McInnes output where only the first processor opens 88ef5ee4d1SLois Curfman McInnes the file. All other processors send their 89ef5ee4d1SLois Curfman McInnes data to the first processor to print. 90*c655490fSBarry Smith - VIEWER_DRAW_WORLD - graphical display of nonzero structure 91bbf0e169SBarry Smith 92639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 93005c665bSBarry Smith 94b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, view 95bbf0e169SBarry Smith @*/ 96b4fc646aSLois Curfman McInnes int MatFDColoringView(MatFDColoring c,Viewer viewer) 97bbf0e169SBarry Smith { 98005c665bSBarry Smith ViewerType vtype; 99639f9d9dSBarry Smith int i,j,format,ierr; 100bbf0e169SBarry Smith 1013a40ed3dSBarry Smith PetscFunctionBegin; 102b4fc646aSLois Curfman McInnes PetscValidHeaderSpecific(c,MAT_FDCOLORING_COOKIE); 103b4fc646aSLois Curfman McInnes if (viewer) {PetscValidHeader(viewer);} 104b4fc646aSLois Curfman McInnes else {viewer = VIEWER_STDOUT_SELF;} 105bbf0e169SBarry Smith 106005c665bSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 1073f1db9ecSBarry Smith if (PetscTypeCompare(vtype,DRAW_VIEWER)) { 108b4fc646aSLois Curfman McInnes ierr = MatFDColoringView_Draw(c,viewer); CHKERRQ(ierr); 1093a40ed3dSBarry Smith PetscFunctionReturn(0); 1103f1db9ecSBarry Smith } else if (PetscTypeCompare(vtype,ASCII_VIEWER)) { 1110ef38995SBarry Smith ViewerASCIIPrintf(viewer,"MatFDColoring Object:\n"); 1120ef38995SBarry Smith ViewerASCIIPrintf(viewer," Error tolerance=%g\n",c->error_rel); 1130ef38995SBarry Smith ViewerASCIIPrintf(viewer," Umin=%g\n",c->umin); 1140ef38995SBarry Smith ViewerASCIIPrintf(viewer," Number of colors=%d\n",c->ncolors); 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++ ) { 1190ef38995SBarry Smith ViewerASCIIPrintf(viewer," Information for color %d\n",i); 1200ef38995SBarry Smith ViewerASCIIPrintf(viewer," Number of columns %d\n",c->ncolumns[i]); 121b4fc646aSLois Curfman McInnes for ( j=0; j<c->ncolumns[i]; j++ ) { 1220ef38995SBarry Smith ViewerASCIIPrintf(viewer," %d\n",c->columns[i][j]); 123639f9d9dSBarry Smith } 1240ef38995SBarry Smith ViewerASCIIPrintf(viewer," Number of rows %d\n",c->nrows[i]); 125b4fc646aSLois Curfman McInnes for ( j=0; j<c->nrows[i]; j++ ) { 1260ef38995SBarry Smith ViewerASCIIPrintf(viewer," %d %d \n",c->rows[i][j],c->columnsforrow[i][j]); 127b4fc646aSLois Curfman McInnes } 128bbf0e169SBarry Smith } 129bbf0e169SBarry Smith } 1305cd90555SBarry Smith } else { 1315cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported for this object"); 132bbf0e169SBarry Smith } 1333a40ed3dSBarry Smith PetscFunctionReturn(0); 134639f9d9dSBarry Smith } 135639f9d9dSBarry Smith 1365615d1e5SSatish Balay #undef __FUNC__ 1375615d1e5SSatish Balay #define __FUNC__ "MatFDColoringSetParameters" 138639f9d9dSBarry Smith /*@ 139b4fc646aSLois Curfman McInnes MatFDColoringSetParameters - Sets the parameters for the sparse approximation of 140b4fc646aSLois Curfman McInnes a Jacobian matrix using finite differences. 141639f9d9dSBarry Smith 142ef5ee4d1SLois Curfman McInnes Collective on MatFDColoring 143ef5ee4d1SLois Curfman McInnes 144ef5ee4d1SLois Curfman McInnes The Jacobian is estimated with the differencing approximation 145ef5ee4d1SLois Curfman McInnes .vb 146ef5ee4d1SLois Curfman McInnes J(u)_{:,i} = [J(u+h*dx_{i}) - J(u)]/h where 147f23b5b22SLois Curfman McInnes h = error_rel*u[i] if abs(u[i]) > umin 148f23b5b22SLois Curfman McInnes = +/- error_rel*umin otherwise, with +/- determined by the sign of u[i] 149ef5ee4d1SLois Curfman McInnes dx_{i} = (0, ... 1, .... 0) 150ef5ee4d1SLois Curfman McInnes .ve 151639f9d9dSBarry Smith 152639f9d9dSBarry Smith Input Parameters: 153ef5ee4d1SLois Curfman McInnes + coloring - the coloring context 154639f9d9dSBarry Smith . error_rel - relative error 155f23b5b22SLois Curfman McInnes - umin - minimum allowable u-value magnitude 156fee21e36SBarry Smith 157b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, parameters 158b4fc646aSLois Curfman McInnes 159b4fc646aSLois Curfman McInnes .seealso: MatFDColoringCreate() 160639f9d9dSBarry Smith @*/ 161639f9d9dSBarry Smith int MatFDColoringSetParameters(MatFDColoring matfd,double error,double umin) 162639f9d9dSBarry Smith { 1633a40ed3dSBarry Smith PetscFunctionBegin; 164639f9d9dSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 165639f9d9dSBarry Smith 166639f9d9dSBarry Smith if (error != PETSC_DEFAULT) matfd->error_rel = error; 167639f9d9dSBarry Smith if (umin != PETSC_DEFAULT) matfd->umin = umin; 1683a40ed3dSBarry Smith PetscFunctionReturn(0); 169639f9d9dSBarry Smith } 170639f9d9dSBarry Smith 1715615d1e5SSatish Balay #undef __FUNC__ 172005c665bSBarry Smith #define __FUNC__ "MatFDColoringSetFrequency" 173005c665bSBarry Smith /*@ 174e0907662SLois Curfman McInnes MatFDColoringSetFrequency - Sets the frequency for computing new Jacobian 175e0907662SLois Curfman McInnes matrices. 176005c665bSBarry Smith 177fee21e36SBarry Smith Collective on MatFDColoring 178fee21e36SBarry Smith 179ef5ee4d1SLois Curfman McInnes Input Parameters: 180ef5ee4d1SLois Curfman McInnes + coloring - the coloring context 181ef5ee4d1SLois Curfman McInnes - freq - frequency (default is 1) 182ef5ee4d1SLois Curfman McInnes 183e0907662SLois Curfman McInnes Notes: 184e0907662SLois Curfman McInnes Using a modified Newton strategy, where the Jacobian remains fixed for several 185e0907662SLois Curfman McInnes iterations, can be cost effective in terms of overall nonlinear solution 186e0907662SLois Curfman McInnes efficiency. This parameter indicates that a new Jacobian will be computed every 187e0907662SLois Curfman McInnes <freq> nonlinear iterations. 188e0907662SLois Curfman McInnes 189e0907662SLois Curfman McInnes Options Database Keys: 190ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_freq <freq> - Sets coloring frequency 191005c665bSBarry Smith 192b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, frequency 193ef5ee4d1SLois Curfman McInnes 194ef5ee4d1SLois Curfman McInnes .seealso: MatFDColoringCreate(), MatFDColoringGetFrequency() 195005c665bSBarry Smith @*/ 196005c665bSBarry Smith int MatFDColoringSetFrequency(MatFDColoring matfd,int freq) 197005c665bSBarry Smith { 1983a40ed3dSBarry Smith PetscFunctionBegin; 199005c665bSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 200005c665bSBarry Smith 201005c665bSBarry Smith matfd->freq = freq; 2023a40ed3dSBarry Smith PetscFunctionReturn(0); 203005c665bSBarry Smith } 204005c665bSBarry Smith 205005c665bSBarry Smith #undef __FUNC__ 206ff0cfa39SBarry Smith #define __FUNC__ "MatFDColoringGetFrequency" 207ff0cfa39SBarry Smith /*@ 208ff0cfa39SBarry Smith MatFDColoringGetFrequency - Gets the frequency for computing new Jacobian 209ff0cfa39SBarry Smith matrices. 210ff0cfa39SBarry Smith 211ef5ee4d1SLois Curfman McInnes Not Collective 212ef5ee4d1SLois Curfman McInnes 213ff0cfa39SBarry Smith Input Parameters: 214ff0cfa39SBarry Smith . coloring - the coloring context 215ff0cfa39SBarry Smith 216ff0cfa39SBarry Smith Output Parameters: 217ff0cfa39SBarry Smith . freq - frequency (default is 1) 218ff0cfa39SBarry Smith 219ff0cfa39SBarry Smith Notes: 220ff0cfa39SBarry Smith Using a modified Newton strategy, where the Jacobian remains fixed for several 221ff0cfa39SBarry Smith iterations, can be cost effective in terms of overall nonlinear solution 222ff0cfa39SBarry Smith efficiency. This parameter indicates that a new Jacobian will be computed every 223ff0cfa39SBarry Smith <freq> nonlinear iterations. 224ff0cfa39SBarry Smith 225ff0cfa39SBarry Smith Options Database Keys: 226ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_freq <freq> - Sets coloring frequency 227ff0cfa39SBarry Smith 228ff0cfa39SBarry Smith .keywords: Mat, finite differences, coloring, get, frequency 229ef5ee4d1SLois Curfman McInnes 230ef5ee4d1SLois Curfman McInnes .seealso: MatFDColoringSetFrequency() 231ff0cfa39SBarry Smith @*/ 232ff0cfa39SBarry Smith int MatFDColoringGetFrequency(MatFDColoring matfd,int *freq) 233ff0cfa39SBarry Smith { 2343a40ed3dSBarry Smith PetscFunctionBegin; 235ff0cfa39SBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 236ff0cfa39SBarry Smith 237ff0cfa39SBarry Smith *freq = matfd->freq; 2383a40ed3dSBarry Smith PetscFunctionReturn(0); 239ff0cfa39SBarry Smith } 240ff0cfa39SBarry Smith 241ff0cfa39SBarry Smith #undef __FUNC__ 242005c665bSBarry Smith #define __FUNC__ "MatFDColoringSetFunction" 243d64ed03dSBarry Smith /*@C 244005c665bSBarry Smith MatFDColoringSetFunction - Sets the function to use for computing the Jacobian. 245005c665bSBarry Smith 246fee21e36SBarry Smith Collective on MatFDColoring 247fee21e36SBarry Smith 248ef5ee4d1SLois Curfman McInnes Input Parameters: 249ef5ee4d1SLois Curfman McInnes + coloring - the coloring context 250ef5ee4d1SLois Curfman McInnes . f - the function 251ef5ee4d1SLois Curfman McInnes - fctx - the optional user-defined function context 252ef5ee4d1SLois Curfman McInnes 253b4fc646aSLois Curfman McInnes .keywords: Mat, Jacobian, finite differences, set, function 254005c665bSBarry Smith @*/ 255840b8ebdSBarry Smith int MatFDColoringSetFunction(MatFDColoring matfd,int (*f)(void),void *fctx) 256005c665bSBarry Smith { 2573a40ed3dSBarry Smith PetscFunctionBegin; 258005c665bSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 259005c665bSBarry Smith 260005c665bSBarry Smith matfd->f = f; 261005c665bSBarry Smith matfd->fctx = fctx; 262005c665bSBarry Smith 2633a40ed3dSBarry Smith PetscFunctionReturn(0); 264005c665bSBarry Smith } 265005c665bSBarry Smith 266005c665bSBarry Smith #undef __FUNC__ 267d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringSetFromOptions" 268639f9d9dSBarry Smith /*@ 269b4fc646aSLois Curfman McInnes MatFDColoringSetFromOptions - Sets coloring finite difference parameters from 270639f9d9dSBarry Smith the options database. 271639f9d9dSBarry Smith 272fee21e36SBarry Smith Collective on MatFDColoring 273fee21e36SBarry Smith 274ef5ee4d1SLois Curfman McInnes The Jacobian is estimated with the differencing approximation 275ef5ee4d1SLois Curfman McInnes .vb 276ef5ee4d1SLois Curfman McInnes J(u)_{:,i} = [J(u+h*dx_{i}) - J(u)]/h where 277f23b5b22SLois Curfman McInnes h = error_rel*u[i] if abs(u[i]) > umin 278f23b5b22SLois Curfman McInnes = +/- error_rel*umin otherwise, with +/- determined by the sign of u[i] 279ef5ee4d1SLois Curfman McInnes dx_{i} = (0, ... 1, .... 0) 280ef5ee4d1SLois Curfman McInnes .ve 281ef5ee4d1SLois Curfman McInnes 282ef5ee4d1SLois Curfman McInnes Input Parameter: 283ef5ee4d1SLois Curfman McInnes . coloring - the coloring context 284ef5ee4d1SLois Curfman McInnes 285b4fc646aSLois Curfman McInnes Options Database Keys: 286ef5ee4d1SLois Curfman McInnes + -mat_fd_coloring_error <err> - Sets <err> (square root 287ef5ee4d1SLois Curfman McInnes of relative error in the function) 288f23b5b22SLois Curfman McInnes . -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude 289ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_freq <freq> - Sets frequency of computing a new Jacobian 290ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_view - Activates basic viewing 291ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_view_info - Activates viewing info 292ef5ee4d1SLois Curfman McInnes - -mat_fd_coloring_view_draw - Activates drawing 293639f9d9dSBarry Smith 294b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, parameters 295639f9d9dSBarry Smith @*/ 296639f9d9dSBarry Smith int MatFDColoringSetFromOptions(MatFDColoring matfd) 297639f9d9dSBarry Smith { 298005c665bSBarry Smith int ierr,flag,freq = 1; 299639f9d9dSBarry Smith double error = PETSC_DEFAULT,umin = PETSC_DEFAULT; 3003a40ed3dSBarry Smith 3013a40ed3dSBarry Smith PetscFunctionBegin; 302639f9d9dSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 303639f9d9dSBarry Smith 304639f9d9dSBarry Smith ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_err",&error,&flag);CHKERRQ(ierr); 305639f9d9dSBarry Smith ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_umin",&umin,&flag);CHKERRQ(ierr); 306639f9d9dSBarry Smith ierr = MatFDColoringSetParameters(matfd,error,umin); CHKERRQ(ierr); 307005c665bSBarry Smith ierr = OptionsGetInt(matfd->prefix,"-mat_fd_coloring_freq",&freq,&flag);CHKERRQ(ierr); 308005c665bSBarry Smith ierr = MatFDColoringSetFrequency(matfd,freq);CHKERRQ(ierr); 309005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help",&flag); CHKERRQ(ierr); 310639f9d9dSBarry Smith if (flag) { 311639f9d9dSBarry Smith ierr = MatFDColoringPrintHelp(matfd); CHKERRQ(ierr); 312639f9d9dSBarry Smith } 3133a40ed3dSBarry Smith PetscFunctionReturn(0); 314639f9d9dSBarry Smith } 315639f9d9dSBarry Smith 3165615d1e5SSatish Balay #undef __FUNC__ 317d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringPrintHelp" 318639f9d9dSBarry Smith /*@ 319639f9d9dSBarry Smith MatFDColoringPrintHelp - Prints help message for matrix finite difference calculations 320639f9d9dSBarry Smith using coloring. 321639f9d9dSBarry Smith 322ef5ee4d1SLois Curfman McInnes Collective on MatFDColoring 323ef5ee4d1SLois Curfman McInnes 324639f9d9dSBarry Smith Input Parameter: 325639f9d9dSBarry Smith . fdcoloring - the MatFDColoring context 326639f9d9dSBarry Smith 327639f9d9dSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringSetFromOptions() 328639f9d9dSBarry Smith @*/ 329639f9d9dSBarry Smith int MatFDColoringPrintHelp(MatFDColoring fd) 330639f9d9dSBarry Smith { 3313a40ed3dSBarry Smith PetscFunctionBegin; 332639f9d9dSBarry Smith PetscValidHeaderSpecific(fd,MAT_FDCOLORING_COOKIE); 333639f9d9dSBarry Smith 33476be9ce4SBarry Smith (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_err <err>: set sqrt rel tol in function, defaults to %g\n",fd->error_rel); 33576be9ce4SBarry Smith (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_umin <umin>: see users manual, defaults to %d\n",fd->umin); 33676be9ce4SBarry Smith (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_freq <freq>: frequency that Jacobian is recomputed, defaults to %d\n",fd->freq); 33776be9ce4SBarry Smith (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view\n"); 33876be9ce4SBarry Smith (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view_draw\n"); 33976be9ce4SBarry Smith (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view_info\n"); 3403a40ed3dSBarry Smith PetscFunctionReturn(0); 341005c665bSBarry Smith } 342005c665bSBarry Smith 343005c665bSBarry Smith int MatFDColoringView_Private(MatFDColoring fd) 344005c665bSBarry Smith { 345005c665bSBarry Smith int ierr,flg; 346005c665bSBarry Smith 3473a40ed3dSBarry Smith PetscFunctionBegin; 348005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view",&flg); CHKERRQ(ierr); 349005c665bSBarry Smith if (flg) { 350f8590f6eSBarry Smith ierr = MatFDColoringView(fd,VIEWER_STDOUT_(fd->comm)); CHKERRQ(ierr); 351005c665bSBarry Smith } 352ae09f205SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view_info",&flg); CHKERRQ(ierr); 353ae09f205SBarry Smith if (flg) { 354f8590f6eSBarry Smith ierr = ViewerPushFormat(VIEWER_STDOUT_(fd->comm),VIEWER_FORMAT_ASCII_INFO,PETSC_NULL);CHKERRQ(ierr); 355f8590f6eSBarry Smith ierr = MatFDColoringView(fd,VIEWER_STDOUT_(fd->comm)); CHKERRQ(ierr); 356f8590f6eSBarry Smith ierr = ViewerPopFormat(VIEWER_STDOUT_(fd->comm));CHKERRQ(ierr); 357ae09f205SBarry Smith } 358005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view_draw",&flg); CHKERRQ(ierr); 359005c665bSBarry Smith if (flg) { 360*c655490fSBarry Smith ierr = MatFDColoringView(fd,VIEWER_DRAW_(fd->comm)); CHKERRQ(ierr); 361*c655490fSBarry Smith ierr = ViewerFlush(VIEWER_DRAW_(fd->comm)); CHKERRQ(ierr); 362005c665bSBarry Smith } 3633a40ed3dSBarry Smith PetscFunctionReturn(0); 364bbf0e169SBarry Smith } 365bbf0e169SBarry Smith 3665615d1e5SSatish Balay #undef __FUNC__ 3675615d1e5SSatish Balay #define __FUNC__ "MatFDColoringCreate" 368bbf0e169SBarry Smith /*@C 369639f9d9dSBarry Smith MatFDColoringCreate - Creates a matrix coloring context for finite difference 370639f9d9dSBarry Smith computation of Jacobians. 371bbf0e169SBarry Smith 372ef5ee4d1SLois Curfman McInnes Collective on Mat 373ef5ee4d1SLois Curfman McInnes 374639f9d9dSBarry Smith Input Parameters: 375ef5ee4d1SLois Curfman McInnes + mat - the matrix containing the nonzero structure of the Jacobian 376ef5ee4d1SLois Curfman McInnes - iscoloring - the coloring of the matrix 377bbf0e169SBarry Smith 378bbf0e169SBarry Smith Output Parameter: 379639f9d9dSBarry Smith . color - the new coloring context 380bbf0e169SBarry Smith 381b4fc646aSLois Curfman McInnes Options Database Keys: 382ef5ee4d1SLois Curfman McInnes + -mat_fd_coloring_view - Activates basic viewing or coloring 383ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_view_draw - Activates drawing of coloring 384ef5ee4d1SLois Curfman McInnes - -mat_fd_coloring_view_info - Activates viewing of coloring info 385639f9d9dSBarry Smith 386639f9d9dSBarry Smith .seealso: MatFDColoringDestroy() 387bbf0e169SBarry Smith @*/ 388639f9d9dSBarry Smith int MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color) 389bbf0e169SBarry Smith { 390639f9d9dSBarry Smith MatFDColoring c; 391639f9d9dSBarry Smith MPI_Comm comm; 392639f9d9dSBarry Smith int ierr,M,N; 393639f9d9dSBarry Smith 3943a40ed3dSBarry Smith PetscFunctionBegin; 395639f9d9dSBarry Smith ierr = MatGetSize(mat,&M,&N); CHKERRQ(ierr); 396e3372554SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Only for square matrices"); 397639f9d9dSBarry Smith 398639f9d9dSBarry Smith PetscObjectGetComm((PetscObject)mat,&comm); 3993f1db9ecSBarry Smith PetscHeaderCreate(c,_p_MatFDColoring,int,MAT_FDCOLORING_COOKIE,0,"MatFDColoring",comm, 4003f1db9ecSBarry Smith MatFDColoringDestroy,MatFDColoringView); 401639f9d9dSBarry Smith PLogObjectCreate(c); 402639f9d9dSBarry Smith 403f830108cSBarry Smith if (mat->ops->fdcoloringcreate) { 404f830108cSBarry Smith ierr = (*mat->ops->fdcoloringcreate)(mat,iscoloring,c); CHKERRQ(ierr); 405639f9d9dSBarry Smith } else { 406e3372554SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Code not yet written for this matrix type"); 407639f9d9dSBarry Smith } 408639f9d9dSBarry Smith 409639f9d9dSBarry Smith c->error_rel = 1.e-8; 410ae09f205SBarry Smith c->umin = 1.e-6; 411005c665bSBarry Smith c->freq = 1; 412005c665bSBarry Smith 413005c665bSBarry Smith ierr = MatFDColoringView_Private(c); CHKERRQ(ierr); 414639f9d9dSBarry Smith 415639f9d9dSBarry Smith *color = c; 416639f9d9dSBarry Smith 4173a40ed3dSBarry Smith PetscFunctionReturn(0); 418bbf0e169SBarry Smith } 419bbf0e169SBarry Smith 4205615d1e5SSatish Balay #undef __FUNC__ 421d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringDestroy" 422bbf0e169SBarry Smith /*@C 423639f9d9dSBarry Smith MatFDColoringDestroy - Destroys a matrix coloring context that was created 424639f9d9dSBarry Smith via MatFDColoringCreate(). 425bbf0e169SBarry Smith 426ef5ee4d1SLois Curfman McInnes Collective on MatFDColoring 427ef5ee4d1SLois Curfman McInnes 428b4fc646aSLois Curfman McInnes Input Parameter: 429639f9d9dSBarry Smith . c - coloring context 430bbf0e169SBarry Smith 431639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 432bbf0e169SBarry Smith @*/ 433639f9d9dSBarry Smith int MatFDColoringDestroy(MatFDColoring c) 434bbf0e169SBarry Smith { 435263760aaSBarry Smith int i,ierr; 436bbf0e169SBarry Smith 4373a40ed3dSBarry Smith PetscFunctionBegin; 4383a40ed3dSBarry Smith if (--c->refct > 0) PetscFunctionReturn(0); 439d4bb536fSBarry Smith 440639f9d9dSBarry Smith 441639f9d9dSBarry Smith for ( i=0; i<c->ncolors; i++ ) { 442639f9d9dSBarry Smith if (c->columns[i]) PetscFree(c->columns[i]); 443639f9d9dSBarry Smith if (c->rows[i]) PetscFree(c->rows[i]); 444639f9d9dSBarry Smith if (c->columnsforrow[i]) PetscFree(c->columnsforrow[i]); 445bbf0e169SBarry Smith } 446639f9d9dSBarry Smith PetscFree(c->ncolumns); 447639f9d9dSBarry Smith PetscFree(c->columns); 448639f9d9dSBarry Smith PetscFree(c->nrows); 449639f9d9dSBarry Smith PetscFree(c->rows); 450639f9d9dSBarry Smith PetscFree(c->columnsforrow); 451639f9d9dSBarry Smith PetscFree(c->scale); 452005c665bSBarry Smith if (c->w1) { 453005c665bSBarry Smith ierr = VecDestroy(c->w1); CHKERRQ(ierr); 454005c665bSBarry Smith ierr = VecDestroy(c->w2); CHKERRQ(ierr); 455005c665bSBarry Smith ierr = VecDestroy(c->w3); CHKERRQ(ierr); 456005c665bSBarry Smith } 457639f9d9dSBarry Smith PLogObjectDestroy(c); 458639f9d9dSBarry Smith PetscHeaderDestroy(c); 4593a40ed3dSBarry Smith PetscFunctionReturn(0); 460bbf0e169SBarry Smith } 46143a90d84SBarry Smith 462005c665bSBarry Smith #include "snes.h" 463005c665bSBarry Smith 4645615d1e5SSatish Balay #undef __FUNC__ 4655615d1e5SSatish Balay #define __FUNC__ "MatFDColoringApply" 46643a90d84SBarry Smith /*@ 467e0907662SLois Curfman McInnes MatFDColoringApply - Given a matrix for which a MatFDColoring context 468e0907662SLois Curfman McInnes has been created, computes the Jacobian for a function via finite differences. 46943a90d84SBarry Smith 470fee21e36SBarry Smith Collective on MatFDColoring 471fee21e36SBarry Smith 472ef5ee4d1SLois Curfman McInnes Input Parameters: 473ef5ee4d1SLois Curfman McInnes + mat - location to store Jacobian 474ef5ee4d1SLois Curfman McInnes . coloring - coloring context created with MatFDColoringCreate() 475ef5ee4d1SLois Curfman McInnes . x1 - location at which Jacobian is to be computed 476ef5ee4d1SLois Curfman McInnes - sctx - optional context required by function (actually a SNES context) 477ef5ee4d1SLois Curfman McInnes 4788bba8e72SBarry Smith Options Database Keys: 479ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_freq <freq> - Sets coloring frequency 4808bba8e72SBarry Smith 48143a90d84SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView() 48243a90d84SBarry Smith 48343a90d84SBarry Smith .keywords: coloring, Jacobian, finite differences 48443a90d84SBarry Smith @*/ 485005c665bSBarry Smith int MatFDColoringApply(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 48643a90d84SBarry Smith { 487e0907662SLois Curfman McInnes int k,fg,ierr,N,start,end,l,row,col,srow; 48843a90d84SBarry Smith Scalar dx, mone = -1.0,*y,*scale = coloring->scale,*xx,*wscale = coloring->wscale; 48943a90d84SBarry Smith double epsilon = coloring->error_rel, umin = coloring->umin; 49043a90d84SBarry Smith MPI_Comm comm = coloring->comm; 491005c665bSBarry Smith Vec w1,w2,w3; 492840b8ebdSBarry Smith int (*f)(void *,Vec,Vec,void *) = ( int (*)(void *,Vec,Vec,void *))coloring->f; 493005c665bSBarry Smith void *fctx = coloring->fctx; 494005c665bSBarry Smith 4953a40ed3dSBarry Smith PetscFunctionBegin; 496e0907662SLois Curfman McInnes PetscValidHeaderSpecific(J,MAT_COOKIE); 497e0907662SLois Curfman McInnes PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_COOKIE); 498e0907662SLois Curfman McInnes PetscValidHeaderSpecific(x1,VEC_COOKIE); 499e0907662SLois Curfman McInnes 500005c665bSBarry Smith 501005c665bSBarry Smith if (!coloring->w1) { 502005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w1); CHKERRQ(ierr); 503005c665bSBarry Smith PLogObjectParent(coloring,coloring->w1); 504005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w2); CHKERRQ(ierr); 505005c665bSBarry Smith PLogObjectParent(coloring,coloring->w2); 506005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w3); CHKERRQ(ierr); 507005c665bSBarry Smith PLogObjectParent(coloring,coloring->w3); 508005c665bSBarry Smith } 509005c665bSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 51043a90d84SBarry Smith 511e0907662SLois Curfman McInnes ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&fg); CHKERRQ(ierr); 512e0907662SLois Curfman McInnes if (fg) { 513e0907662SLois Curfman McInnes PLogInfo(coloring,"MatFDColoringApply: Not calling MatZeroEntries()\n"); 514e0907662SLois Curfman McInnes } else { 51543a90d84SBarry Smith ierr = MatZeroEntries(J); CHKERRQ(ierr); 516e0907662SLois Curfman McInnes } 51743a90d84SBarry Smith 51843a90d84SBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end); CHKERRQ(ierr); 51943a90d84SBarry Smith ierr = VecGetSize(x1,&N); CHKERRQ(ierr); 52043a90d84SBarry Smith ierr = (*f)(sctx,x1,w1,fctx); CHKERRQ(ierr); 52143a90d84SBarry Smith 52243a90d84SBarry Smith PetscMemzero(wscale,N*sizeof(Scalar)); 52343a90d84SBarry Smith /* 52443a90d84SBarry Smith Loop over each color 52543a90d84SBarry Smith */ 52643a90d84SBarry Smith 5273b28642cSBarry Smith ierr = VecGetArray(x1,&xx); CHKERRQ(ierr); 52843a90d84SBarry Smith for (k=0; k<coloring->ncolors; k++) { 52943a90d84SBarry Smith ierr = VecCopy(x1,w3); CHKERRQ(ierr); 53043a90d84SBarry Smith /* 53143a90d84SBarry Smith Loop over each column associated with color adding the 53243a90d84SBarry Smith perturbation to the vector w3. 53343a90d84SBarry Smith */ 53443a90d84SBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 53543a90d84SBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 53643a90d84SBarry Smith dx = xx[col-start]; 537ae09f205SBarry Smith if (dx == 0.0) dx = 1.0; 5383a40ed3dSBarry Smith #if !defined(USE_PETSC_COMPLEX) 539ae09f205SBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 540ae09f205SBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 54143a90d84SBarry Smith #else 542e20fef11SSatish Balay if (PetscAbsScalar(dx) < umin && PetscReal(dx) >= 0.0) dx = umin; 543e20fef11SSatish Balay else if (PetscReal(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 54443a90d84SBarry Smith #endif 54543a90d84SBarry Smith dx *= epsilon; 54643a90d84SBarry Smith wscale[col] = 1.0/dx; 5473b28642cSBarry Smith ierr = VecSetValues(w3,1,&col,&dx,ADD_VALUES);CHKERRQ(ierr); 54843a90d84SBarry Smith } 5493b28642cSBarry Smith 55043a90d84SBarry Smith /* 551e0907662SLois Curfman McInnes Evaluate function at x1 + dx (here dx is a vector of perturbations) 55243a90d84SBarry Smith */ 55343a90d84SBarry Smith ierr = (*f)(sctx,w3,w2,fctx); CHKERRQ(ierr); 55443a90d84SBarry Smith ierr = VecAXPY(&mone,w1,w2); CHKERRQ(ierr); 55543a90d84SBarry Smith /* Communicate scale to all processors */ 5563a40ed3dSBarry Smith #if !defined(USE_PETSC_COMPLEX) 557ca161407SBarry Smith ierr = MPI_Allreduce(wscale,scale,N,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr); 55843a90d84SBarry Smith #else 559ca161407SBarry Smith ierr = MPI_Allreduce(wscale,scale,2*N,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr); 56043a90d84SBarry Smith #endif 56143a90d84SBarry Smith /* 562e0907662SLois Curfman McInnes Loop over rows of vector, putting results into Jacobian matrix 56343a90d84SBarry Smith */ 5643b28642cSBarry Smith ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 56543a90d84SBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 56643a90d84SBarry Smith row = coloring->rows[k][l]; 56743a90d84SBarry Smith col = coloring->columnsforrow[k][l]; 56843a90d84SBarry Smith y[row] *= scale[col]; 56943a90d84SBarry Smith srow = row + start; 57043a90d84SBarry Smith ierr = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 57143a90d84SBarry Smith } 5723b28642cSBarry Smith ierr = VecRestoreArray(w2,&y); CHKERRQ(ierr); 57343a90d84SBarry Smith } 5743b28642cSBarry Smith ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 57543a90d84SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 57643a90d84SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 5773a40ed3dSBarry Smith PetscFunctionReturn(0); 57843a90d84SBarry Smith } 579840b8ebdSBarry Smith 580840b8ebdSBarry Smith #include "ts.h" 581840b8ebdSBarry Smith 582840b8ebdSBarry Smith #undef __FUNC__ 583840b8ebdSBarry Smith #define __FUNC__ "MatFDColoringApplyTS" 584840b8ebdSBarry Smith /*@ 585840b8ebdSBarry Smith MatFDColoringApplyTS - Given a matrix for which a MatFDColoring context 586840b8ebdSBarry Smith has been created, computes the Jacobian for a function via finite differences. 587840b8ebdSBarry Smith 588fee21e36SBarry Smith Collective on Mat, MatFDColoring, and Vec 589fee21e36SBarry Smith 590ef5ee4d1SLois Curfman McInnes Input Parameters: 5913b28642cSBarry Smith + mat - location to store Jacobian 592ef5ee4d1SLois Curfman McInnes . coloring - coloring context created with MatFDColoringCreate() 593ef5ee4d1SLois Curfman McInnes . x1 - location at which Jacobian is to be computed 594ef5ee4d1SLois Curfman McInnes - sctx - optional context required by function (actually a SNES context) 595ef5ee4d1SLois Curfman McInnes 596840b8ebdSBarry Smith Options Database Keys: 597ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_freq <freq> - Sets coloring frequency 598840b8ebdSBarry Smith 599840b8ebdSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView() 600840b8ebdSBarry Smith 601840b8ebdSBarry Smith .keywords: coloring, Jacobian, finite differences 602840b8ebdSBarry Smith @*/ 603840b8ebdSBarry Smith int MatFDColoringApplyTS(Mat J,MatFDColoring coloring,double t,Vec x1,MatStructure *flag,void *sctx) 604840b8ebdSBarry Smith { 605840b8ebdSBarry Smith int k,fg,ierr,N,start,end,l,row,col,srow; 606840b8ebdSBarry Smith Scalar dx, mone = -1.0,*y,*scale = coloring->scale,*xx,*wscale = coloring->wscale; 607840b8ebdSBarry Smith double epsilon = coloring->error_rel, umin = coloring->umin; 608840b8ebdSBarry Smith MPI_Comm comm = coloring->comm; 609840b8ebdSBarry Smith Vec w1,w2,w3; 610840b8ebdSBarry Smith int (*f)(void *,double,Vec,Vec,void *) = ( int (*)(void *,double,Vec,Vec,void *))coloring->f; 611840b8ebdSBarry Smith void *fctx = coloring->fctx; 612840b8ebdSBarry Smith 6133a40ed3dSBarry Smith PetscFunctionBegin; 614840b8ebdSBarry Smith PetscValidHeaderSpecific(J,MAT_COOKIE); 615840b8ebdSBarry Smith PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_COOKIE); 616840b8ebdSBarry Smith PetscValidHeaderSpecific(x1,VEC_COOKIE); 617840b8ebdSBarry Smith 618840b8ebdSBarry Smith if (!coloring->w1) { 619840b8ebdSBarry Smith ierr = VecDuplicate(x1,&coloring->w1); CHKERRQ(ierr); 620840b8ebdSBarry Smith PLogObjectParent(coloring,coloring->w1); 621840b8ebdSBarry Smith ierr = VecDuplicate(x1,&coloring->w2); CHKERRQ(ierr); 622840b8ebdSBarry Smith PLogObjectParent(coloring,coloring->w2); 623840b8ebdSBarry Smith ierr = VecDuplicate(x1,&coloring->w3); CHKERRQ(ierr); 624840b8ebdSBarry Smith PLogObjectParent(coloring,coloring->w3); 625840b8ebdSBarry Smith } 626840b8ebdSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 627840b8ebdSBarry Smith 628840b8ebdSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&fg); CHKERRQ(ierr); 629840b8ebdSBarry Smith if (fg) { 630840b8ebdSBarry Smith PLogInfo(coloring,"MatFDColoringApplyTS: Not calling MatZeroEntries()\n"); 631840b8ebdSBarry Smith } else { 632840b8ebdSBarry Smith ierr = MatZeroEntries(J); CHKERRQ(ierr); 633840b8ebdSBarry Smith } 634840b8ebdSBarry Smith 635840b8ebdSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end); CHKERRQ(ierr); 636840b8ebdSBarry Smith ierr = VecGetSize(x1,&N); CHKERRQ(ierr); 637840b8ebdSBarry Smith ierr = (*f)(sctx,t,x1,w1,fctx); CHKERRQ(ierr); 638840b8ebdSBarry Smith 639840b8ebdSBarry Smith PetscMemzero(wscale,N*sizeof(Scalar)); 640840b8ebdSBarry Smith /* 641840b8ebdSBarry Smith Loop over each color 642840b8ebdSBarry Smith */ 643840b8ebdSBarry Smith 6443b28642cSBarry Smith ierr = VecGetArray(x1,&xx); CHKERRQ(ierr); 645840b8ebdSBarry Smith for (k=0; k<coloring->ncolors; k++) { 646840b8ebdSBarry Smith ierr = VecCopy(x1,w3); CHKERRQ(ierr); 647840b8ebdSBarry Smith /* 648840b8ebdSBarry Smith Loop over each column associated with color adding the 649840b8ebdSBarry Smith perturbation to the vector w3. 650840b8ebdSBarry Smith */ 651840b8ebdSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 652840b8ebdSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 653840b8ebdSBarry Smith dx = xx[col-start]; 654840b8ebdSBarry Smith if (dx == 0.0) dx = 1.0; 6553a40ed3dSBarry Smith #if !defined(USE_PETSC_COMPLEX) 656840b8ebdSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 657840b8ebdSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 658840b8ebdSBarry Smith #else 659e20fef11SSatish Balay if (PetscAbsScalar(dx) < umin && PetscReal(dx) >= 0.0) dx = umin; 660e20fef11SSatish Balay else if (PetscReal(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 661840b8ebdSBarry Smith #endif 662840b8ebdSBarry Smith dx *= epsilon; 663840b8ebdSBarry Smith wscale[col] = 1.0/dx; 6643b28642cSBarry Smith ierr = VecSetValues(w3,1,&col,&dx,ADD_VALUES); CHKERRQ(ierr); 665840b8ebdSBarry Smith } 666840b8ebdSBarry Smith /* 667840b8ebdSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 668840b8ebdSBarry Smith */ 669840b8ebdSBarry Smith ierr = (*f)(sctx,t,w3,w2,fctx); CHKERRQ(ierr); 670840b8ebdSBarry Smith ierr = VecAXPY(&mone,w1,w2); CHKERRQ(ierr); 671840b8ebdSBarry Smith /* Communicate scale to all processors */ 6723a40ed3dSBarry Smith #if !defined(USE_PETSC_COMPLEX) 673ca161407SBarry Smith ierr = MPI_Allreduce(wscale,scale,N,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr); 674840b8ebdSBarry Smith #else 675ca161407SBarry Smith ierr = MPI_Allreduce(wscale,scale,2*N,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr); 676840b8ebdSBarry Smith #endif 677840b8ebdSBarry Smith /* 678840b8ebdSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 679840b8ebdSBarry Smith */ 6803b28642cSBarry Smith ierr = VecGetArray(w2,&y); CHKERRQ(ierr); 681840b8ebdSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 682840b8ebdSBarry Smith row = coloring->rows[k][l]; 683840b8ebdSBarry Smith col = coloring->columnsforrow[k][l]; 684840b8ebdSBarry Smith y[row] *= scale[col]; 685840b8ebdSBarry Smith srow = row + start; 686840b8ebdSBarry Smith ierr = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 687840b8ebdSBarry Smith } 6883b28642cSBarry Smith ierr = VecRestoreArray(w2,&y); CHKERRQ(ierr); 689840b8ebdSBarry Smith } 6903b28642cSBarry Smith ierr = VecRestoreArray(x1,&xx); CHKERRQ(ierr); 691840b8ebdSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 692840b8ebdSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 6933a40ed3dSBarry Smith PetscFunctionReturn(0); 694840b8ebdSBarry Smith } 6953b28642cSBarry Smith 6963b28642cSBarry Smith 6973b28642cSBarry Smith 698