1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*e0907662SLois Curfman McInnes static char vcid[] = "$Id: fdmatrix.c,v 1.16 1997/09/25 22:39:43 curfman Exp curfman $"; 3bbf0e169SBarry Smith #endif 4bbf0e169SBarry Smith 5bbf0e169SBarry Smith /* 6639f9d9dSBarry Smith This is where the abstract matrix operations are defined that are 7639f9d9dSBarry Smith used for finite difference computations of Jacobians using coloring. 8bbf0e169SBarry Smith */ 9bbf0e169SBarry Smith 10bbf0e169SBarry Smith #include "petsc.h" 11bbf0e169SBarry Smith #include "src/mat/matimpl.h" /*I "mat.h" I*/ 12bbf0e169SBarry Smith #include "src/vec/vecimpl.h" 13bbf0e169SBarry Smith #include "pinclude/pviewer.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 25005c665bSBarry Smith ierr = ViewerDrawGetDraw(viewer,&draw); CHKERRQ(ierr); 26005c665bSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) return 0; 27005c665bSBarry Smith ierr = DrawSyncClear(draw); CHKERRQ(ierr); 28005c665bSBarry Smith 29005c665bSBarry Smith xr = fd->N; yr = fd->M; h = yr/10.0; w = xr/10.0; 30005c665bSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 31005c665bSBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 32005c665bSBarry Smith 33005c665bSBarry Smith /* loop over colors */ 34005c665bSBarry Smith for (i=0; i<fd->ncolors; i++ ) { 35005c665bSBarry Smith for ( j=0; j<fd->nrows[i]; j++ ) { 36005c665bSBarry Smith y = fd->M - fd->rows[i][j] - fd->rstart; 37005c665bSBarry Smith x = fd->columnsforrow[i][j]; 38005c665bSBarry Smith DrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1); 39005c665bSBarry Smith } 40005c665bSBarry Smith } 41005c665bSBarry Smith ierr = DrawSyncFlush(draw); CHKERRQ(ierr); 42005c665bSBarry Smith ierr = DrawGetPause(draw,&pause); CHKERRQ(ierr); 43005c665bSBarry Smith if (pause >= 0) { PetscSleep(pause); return 0;} 44005c665bSBarry Smith ierr = DrawCheckResizedWindow(draw); 45005c665bSBarry Smith ierr = DrawSyncGetMouseButton(draw,&button,&xc,&yc,0,0); 46005c665bSBarry Smith while (button != BUTTON_RIGHT) { 47005c665bSBarry Smith ierr = DrawSyncClear(draw); CHKERRQ(ierr); 48005c665bSBarry Smith if (button == BUTTON_LEFT) scale = .5; 49005c665bSBarry Smith else if (button == BUTTON_CENTER) scale = 2.; 50005c665bSBarry Smith xl = scale*(xl + w - xc) + xc - w*scale; 51005c665bSBarry Smith xr = scale*(xr - w - xc) + xc + w*scale; 52005c665bSBarry Smith yl = scale*(yl + h - yc) + yc - h*scale; 53005c665bSBarry Smith yr = scale*(yr - h - yc) + yc + h*scale; 54005c665bSBarry Smith w *= scale; h *= scale; 55005c665bSBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 56005c665bSBarry Smith /* loop over colors */ 57005c665bSBarry Smith for (i=0; i<fd->ncolors; i++ ) { 58005c665bSBarry Smith for ( j=0; j<fd->nrows[i]; j++ ) { 59005c665bSBarry Smith y = fd->M - fd->rows[i][j] - fd->rstart; 60005c665bSBarry Smith x = fd->columnsforrow[i][j]; 61005c665bSBarry Smith DrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1); 62005c665bSBarry Smith } 63005c665bSBarry Smith } 64005c665bSBarry Smith ierr = DrawCheckResizedWindow(draw); 65005c665bSBarry Smith ierr = DrawSyncGetMouseButton(draw,&button,&xc,&yc,0,0); 66005c665bSBarry Smith } 67005c665bSBarry Smith 68005c665bSBarry Smith return 0; 69005c665bSBarry Smith } 70005c665bSBarry Smith 71005c665bSBarry Smith #undef __FUNC__ 72d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringView" 73bbf0e169SBarry Smith /*@C 74639f9d9dSBarry Smith MatFDColoringView - Views a finite difference coloring context. 75bbf0e169SBarry Smith 76b4fc646aSLois Curfman McInnes Input Parameters: 77b4fc646aSLois Curfman McInnes . c - the coloring context 78b4fc646aSLois Curfman McInnes . viewer - visualization context 79b4fc646aSLois Curfman McInnes 80b4fc646aSLois Curfman McInnes Notes: 81b4fc646aSLois Curfman McInnes The available visualization contexts include 82b4fc646aSLois Curfman McInnes $ VIEWER_STDOUT_SELF - standard output (default) 83b4fc646aSLois Curfman McInnes $ VIEWER_STDOUT_WORLD - synchronized standard 84b4fc646aSLois Curfman McInnes $ output where only the first processor opens 85b4fc646aSLois Curfman McInnes $ the file. All other processors send their 86b4fc646aSLois Curfman McInnes $ data to the first processor to print. 87b4fc646aSLois Curfman McInnes $ VIEWER_DRAWX_WORLD - graphical display of nonzero structure 88bbf0e169SBarry Smith 89639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 90005c665bSBarry Smith 91b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, view 92bbf0e169SBarry Smith @*/ 93b4fc646aSLois Curfman McInnes int MatFDColoringView(MatFDColoring c,Viewer viewer) 94bbf0e169SBarry Smith { 95005c665bSBarry Smith ViewerType vtype; 96639f9d9dSBarry Smith int i,j,format,ierr; 97b4fc646aSLois Curfman McInnes FILE *fd; 98bbf0e169SBarry Smith 99b4fc646aSLois Curfman McInnes PetscValidHeaderSpecific(c,MAT_FDCOLORING_COOKIE); 100b4fc646aSLois Curfman McInnes if (viewer) {PetscValidHeader(viewer);} 101b4fc646aSLois Curfman McInnes else {viewer = VIEWER_STDOUT_SELF;} 102bbf0e169SBarry Smith 103005c665bSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 104005c665bSBarry Smith if (vtype == DRAW_VIEWER) { 105b4fc646aSLois Curfman McInnes ierr = MatFDColoringView_Draw(c,viewer); CHKERRQ(ierr); 106005c665bSBarry Smith return 0; 107005c665bSBarry Smith } 108b4fc646aSLois Curfman McInnes else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER) { 109b4fc646aSLois Curfman McInnes ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 110b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd,"MatFDColoring Object:\n"); 111b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd," Error tolerance=%g\n",c->error_rel); 112b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd," Umin=%g\n",c->umin); 113b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd," Number of colors=%d\n",c->ncolors); 114ae09f205SBarry Smith 115ae09f205SBarry Smith ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr); 116ae09f205SBarry Smith if (format != VIEWER_FORMAT_ASCII_INFO) { 117b4fc646aSLois Curfman McInnes for ( i=0; i<c->ncolors; i++ ) { 118b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd," Information for color %d\n",i); 119b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd," Number of columns %d\n",c->ncolumns[i]); 120b4fc646aSLois Curfman McInnes for ( j=0; j<c->ncolumns[i]; j++ ) { 121b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd," %d\n",c->columns[i][j]); 122639f9d9dSBarry Smith } 123b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd," Number of rows %d\n",c->nrows[i]); 124b4fc646aSLois Curfman McInnes for ( j=0; j<c->nrows[i]; j++ ) { 125b4fc646aSLois Curfman McInnes PetscFPrintf(c->comm,fd," %d %d \n",c->rows[i][j],c->columnsforrow[i][j]); 126b4fc646aSLois Curfman McInnes } 127bbf0e169SBarry Smith } 128bbf0e169SBarry Smith } 129bbf0e169SBarry Smith } 130639f9d9dSBarry Smith return 0; 131639f9d9dSBarry Smith } 132639f9d9dSBarry Smith 1335615d1e5SSatish Balay #undef __FUNC__ 1345615d1e5SSatish Balay #define __FUNC__ "MatFDColoringSetParameters" 135639f9d9dSBarry Smith /*@ 136b4fc646aSLois Curfman McInnes MatFDColoringSetParameters - Sets the parameters for the sparse approximation of 137b4fc646aSLois Curfman McInnes a Jacobian matrix using finite differences. 138639f9d9dSBarry Smith 139639f9d9dSBarry Smith $ J(u)_{:,i} = [J(u+h*dx_{i}) - J(u)]/h where 140639f9d9dSBarry Smith $ h = error_rel*u[i] if u[i] > umin 141639f9d9dSBarry Smith $ = error_rel*umin else 142639f9d9dSBarry Smith $ 143639f9d9dSBarry Smith $ dx_{i} = (0, ... 1, .... 0) 144639f9d9dSBarry Smith 145639f9d9dSBarry Smith Input Parameters: 146b4fc646aSLois Curfman McInnes . coloring - the coloring context 147639f9d9dSBarry Smith . error_rel - relative error 148639f9d9dSBarry Smith . umin - minimum allowable u-value 149639f9d9dSBarry Smith 150b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, parameters 151b4fc646aSLois Curfman McInnes 152b4fc646aSLois Curfman McInnes .seealso: MatFDColoringCreate() 153639f9d9dSBarry Smith @*/ 154639f9d9dSBarry Smith int MatFDColoringSetParameters(MatFDColoring matfd,double error,double umin) 155639f9d9dSBarry Smith { 156639f9d9dSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 157639f9d9dSBarry Smith 158639f9d9dSBarry Smith if (error != PETSC_DEFAULT) matfd->error_rel = error; 159639f9d9dSBarry Smith if (umin != PETSC_DEFAULT) matfd->umin = umin; 160639f9d9dSBarry Smith return 0; 161639f9d9dSBarry Smith } 162639f9d9dSBarry Smith 1635615d1e5SSatish Balay #undef __FUNC__ 164005c665bSBarry Smith #define __FUNC__ "MatFDColoringSetFrequency" 165005c665bSBarry Smith /*@ 166*e0907662SLois Curfman McInnes MatFDColoringSetFrequency - Sets the frequency for computing new Jacobian 167*e0907662SLois Curfman McInnes matrices. 168005c665bSBarry Smith 169005c665bSBarry Smith Input Parameters: 170b4fc646aSLois Curfman McInnes . coloring - the coloring context 171*e0907662SLois Curfman McInnes . freq - frequency (default is 1) 172*e0907662SLois Curfman McInnes 173*e0907662SLois Curfman McInnes Notes: 174*e0907662SLois Curfman McInnes Using a modified Newton strategy, where the Jacobian remains fixed for several 175*e0907662SLois Curfman McInnes iterations, can be cost effective in terms of overall nonlinear solution 176*e0907662SLois Curfman McInnes efficiency. This parameter indicates that a new Jacobian will be computed every 177*e0907662SLois Curfman McInnes <freq> nonlinear iterations. 178*e0907662SLois Curfman McInnes 179*e0907662SLois Curfman McInnes Options Database Keys: 180*e0907662SLois Curfman McInnes $ -mat_fd_coloring_freq <freq> 181005c665bSBarry Smith 182b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, frequency 183005c665bSBarry Smith @*/ 184005c665bSBarry Smith int MatFDColoringSetFrequency(MatFDColoring matfd,int freq) 185005c665bSBarry Smith { 186005c665bSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 187005c665bSBarry Smith 188005c665bSBarry Smith matfd->freq = freq; 189005c665bSBarry Smith return 0; 190005c665bSBarry Smith } 191005c665bSBarry Smith 192005c665bSBarry Smith #undef __FUNC__ 193005c665bSBarry Smith #define __FUNC__ "MatFDColoringSetFunction" 194005c665bSBarry Smith /*@ 195005c665bSBarry Smith MatFDColoringSetFunction - Sets the function to use for computing the Jacobian. 196005c665bSBarry Smith 197005c665bSBarry Smith Input Parameters: 198b4fc646aSLois Curfman McInnes . coloring - the coloring context 199005c665bSBarry Smith . f - the function 200005c665bSBarry Smith . fctx - the function context 201005c665bSBarry Smith 202b4fc646aSLois Curfman McInnes .keywords: Mat, Jacobian, finite differences, set, function 203005c665bSBarry Smith @*/ 204005c665bSBarry Smith int MatFDColoringSetFunction(MatFDColoring matfd,int (*f)(void *,Vec,Vec,void *),void *fctx) 205005c665bSBarry Smith { 206005c665bSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 207005c665bSBarry Smith 208005c665bSBarry Smith matfd->f = f; 209005c665bSBarry Smith matfd->fctx = fctx; 210005c665bSBarry Smith 211005c665bSBarry Smith return 0; 212005c665bSBarry Smith } 213005c665bSBarry Smith 214005c665bSBarry Smith #undef __FUNC__ 215d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringSetFromOptions" 216639f9d9dSBarry Smith /*@ 217b4fc646aSLois Curfman McInnes MatFDColoringSetFromOptions - Sets coloring finite difference parameters from 218639f9d9dSBarry Smith the options database. 219639f9d9dSBarry Smith 220b4fc646aSLois Curfman McInnes The Jacobian is estimated with the differencing approximation 221639f9d9dSBarry Smith $ J(u)_{:,i} = [J(u+h*dx_{i}) - J(u)]/h where 222639f9d9dSBarry Smith $ h = error_rel*u[i] if u[i] > umin 223ae09f205SBarry Smith $ = error_rel*umin else 224639f9d9dSBarry Smith $ 225639f9d9dSBarry Smith $ dx_{i} = (0, ... 1, .... 0) 226639f9d9dSBarry Smith 227639f9d9dSBarry Smith Input Parameters: 228b4fc646aSLois Curfman McInnes . coloring - the coloring context 229639f9d9dSBarry Smith 230b4fc646aSLois Curfman McInnes Options Database Keys: 231b4fc646aSLois Curfman McInnes $ -mat_fd_coloring_error <err>, where <err> is the square root 232b4fc646aSLois Curfman McInnes $ of relative error in the function 233b4fc646aSLois Curfman McInnes $ -mat_fd_coloring_umin <umin>, where umin is described above 234*e0907662SLois Curfman McInnes $ -mat_fd_coloring_freq <freq> where <freq> is the frequency of 235*e0907662SLois Curfman McInnes $ computing a new Jacobian 236639f9d9dSBarry Smith 237b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, parameters 238639f9d9dSBarry Smith @*/ 239639f9d9dSBarry Smith int MatFDColoringSetFromOptions(MatFDColoring matfd) 240639f9d9dSBarry Smith { 241005c665bSBarry Smith int ierr,flag,freq = 1; 242639f9d9dSBarry Smith double error = PETSC_DEFAULT,umin = PETSC_DEFAULT; 243639f9d9dSBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE); 244639f9d9dSBarry Smith 245639f9d9dSBarry Smith ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_err",&error,&flag);CHKERRQ(ierr); 246639f9d9dSBarry Smith ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_umin",&umin,&flag);CHKERRQ(ierr); 247639f9d9dSBarry Smith ierr = MatFDColoringSetParameters(matfd,error,umin); CHKERRQ(ierr); 248005c665bSBarry Smith ierr = OptionsGetInt(matfd->prefix,"-mat_fd_coloring_freq",&freq,&flag);CHKERRQ(ierr); 249005c665bSBarry Smith ierr = MatFDColoringSetFrequency(matfd,freq);CHKERRQ(ierr); 250005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help",&flag); CHKERRQ(ierr); 251639f9d9dSBarry Smith if (flag) { 252639f9d9dSBarry Smith ierr = MatFDColoringPrintHelp(matfd); CHKERRQ(ierr); 253639f9d9dSBarry Smith } 254639f9d9dSBarry Smith return 0; 255639f9d9dSBarry Smith } 256639f9d9dSBarry Smith 2575615d1e5SSatish Balay #undef __FUNC__ 258d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringPrintHelp" 259639f9d9dSBarry Smith /*@ 260639f9d9dSBarry Smith MatFDColoringPrintHelp - Prints help message for matrix finite difference calculations 261639f9d9dSBarry Smith using coloring. 262639f9d9dSBarry Smith 263639f9d9dSBarry Smith Input Parameter: 264639f9d9dSBarry Smith . fdcoloring - the MatFDColoring context 265639f9d9dSBarry Smith 266639f9d9dSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringSetFromOptions() 267639f9d9dSBarry Smith @*/ 268639f9d9dSBarry Smith int MatFDColoringPrintHelp(MatFDColoring fd) 269639f9d9dSBarry Smith { 270639f9d9dSBarry Smith PetscValidHeaderSpecific(fd,MAT_FDCOLORING_COOKIE); 271639f9d9dSBarry Smith 272*e0907662SLois Curfman McInnes PetscPrintf(fd->comm,"-mat_fd_coloring_err <err>: set sqrt rel tol in function, defaults to %g\n",fd->error_rel); 273*e0907662SLois Curfman McInnes PetscPrintf(fd->comm,"-mat_fd_coloring_umin <umin>: see users manual, defaults to %d\n",fd->umin); 274*e0907662SLois Curfman McInnes PetscPrintf(fd->comm,"-mat_fd_coloring_freq <freq>: frequency that Jacobian is recomputed, defaults to %d\n",fd->freq); 275005c665bSBarry Smith PetscPrintf(fd->comm,"-mat_fd_coloring_view\n"); 276005c665bSBarry Smith PetscPrintf(fd->comm,"-mat_fd_coloring_view_draw\n"); 277ae09f205SBarry Smith PetscPrintf(fd->comm,"-mat_fd_coloring_view_info\n"); 278005c665bSBarry Smith return 0; 279005c665bSBarry Smith } 280005c665bSBarry Smith 281005c665bSBarry Smith int MatFDColoringView_Private(MatFDColoring fd) 282005c665bSBarry Smith { 283005c665bSBarry Smith int ierr,flg; 284005c665bSBarry Smith 285005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view",&flg); CHKERRQ(ierr); 286005c665bSBarry Smith if (flg) { 287005c665bSBarry Smith Viewer viewer; 288005c665bSBarry Smith ierr = ViewerFileOpenASCII(fd->comm,"stdout",&viewer);CHKERRQ(ierr); 289005c665bSBarry Smith ierr = MatFDColoringView(fd,viewer); CHKERRQ(ierr); 290005c665bSBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 291005c665bSBarry Smith } 292ae09f205SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view_info",&flg); CHKERRQ(ierr); 293ae09f205SBarry Smith if (flg) { 294ae09f205SBarry Smith Viewer viewer; 295ae09f205SBarry Smith ierr = ViewerFileOpenASCII(fd->comm,"stdout",&viewer);CHKERRQ(ierr); 296ae09f205SBarry Smith ierr = ViewerPushFormat(viewer,VIEWER_FORMAT_ASCII_INFO,PETSC_NULL);CHKERRQ(ierr); 297ae09f205SBarry Smith ierr = MatFDColoringView(fd,viewer); CHKERRQ(ierr); 298ae09f205SBarry Smith ierr = ViewerPopFormat(viewer);CHKERRQ(ierr); 299ae09f205SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 300ae09f205SBarry Smith } 301005c665bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view_draw",&flg); CHKERRQ(ierr); 302005c665bSBarry Smith if (flg) { 303005c665bSBarry Smith ierr = MatFDColoringView(fd,VIEWER_DRAWX_(fd->comm)); CHKERRQ(ierr); 304005c665bSBarry Smith ierr = ViewerFlush(VIEWER_DRAWX_(fd->comm)); CHKERRQ(ierr); 305005c665bSBarry Smith } 306bbf0e169SBarry Smith return 0; 307bbf0e169SBarry Smith } 308bbf0e169SBarry Smith 3095615d1e5SSatish Balay #undef __FUNC__ 3105615d1e5SSatish Balay #define __FUNC__ "MatFDColoringCreate" 311bbf0e169SBarry Smith /*@C 312639f9d9dSBarry Smith MatFDColoringCreate - Creates a matrix coloring context for finite difference 313639f9d9dSBarry Smith computation of Jacobians. 314bbf0e169SBarry Smith 315639f9d9dSBarry Smith Input Parameters: 316639f9d9dSBarry Smith . mat - the matrix containing the nonzero structure of the Jacobian 317639f9d9dSBarry Smith . iscoloring - the coloring of the matrix 318bbf0e169SBarry Smith 319bbf0e169SBarry Smith Output Parameter: 320639f9d9dSBarry Smith . color - the new coloring context 321bbf0e169SBarry Smith 322b4fc646aSLois Curfman McInnes Options Database Keys: 323b4fc646aSLois Curfman McInnes $ -mat_fd_coloring_view 324b4fc646aSLois Curfman McInnes $ -mat_fd_coloring_view_draw 325b4fc646aSLois Curfman McInnes $ -mat_fd_coloring_view_info 326639f9d9dSBarry Smith 327639f9d9dSBarry Smith .seealso: MatFDColoringDestroy() 328bbf0e169SBarry Smith @*/ 329639f9d9dSBarry Smith int MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color) 330bbf0e169SBarry Smith { 331639f9d9dSBarry Smith MatFDColoring c; 332639f9d9dSBarry Smith MPI_Comm comm; 333639f9d9dSBarry Smith int ierr,M,N; 334639f9d9dSBarry Smith 335639f9d9dSBarry Smith ierr = MatGetSize(mat,&M,&N); CHKERRQ(ierr); 336e3372554SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Only for square matrices"); 337639f9d9dSBarry Smith 338639f9d9dSBarry Smith PetscObjectGetComm((PetscObject)mat,&comm); 339d4bb536fSBarry Smith PetscHeaderCreate(c,_p_MatFDColoring,MAT_FDCOLORING_COOKIE,0,comm,MatFDColoringDestroy,MatFDColoringView); 340639f9d9dSBarry Smith PLogObjectCreate(c); 341639f9d9dSBarry Smith 342639f9d9dSBarry Smith if (mat->ops.fdcoloringcreate) { 343639f9d9dSBarry Smith ierr = (*mat->ops.fdcoloringcreate)(mat,iscoloring,c); CHKERRQ(ierr); 344639f9d9dSBarry Smith } else { 345e3372554SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Code not yet written for this matrix type"); 346639f9d9dSBarry Smith } 347639f9d9dSBarry Smith 348639f9d9dSBarry Smith c->error_rel = 1.e-8; 349ae09f205SBarry Smith c->umin = 1.e-6; 350005c665bSBarry Smith c->freq = 1; 351005c665bSBarry Smith 352005c665bSBarry Smith ierr = MatFDColoringView_Private(c); CHKERRQ(ierr); 353639f9d9dSBarry Smith 354639f9d9dSBarry Smith *color = c; 355639f9d9dSBarry Smith 356bbf0e169SBarry Smith return 0; 357bbf0e169SBarry Smith } 358bbf0e169SBarry Smith 3595615d1e5SSatish Balay #undef __FUNC__ 360d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringDestroy" 361bbf0e169SBarry Smith /*@C 362639f9d9dSBarry Smith MatFDColoringDestroy - Destroys a matrix coloring context that was created 363639f9d9dSBarry Smith via MatFDColoringCreate(). 364bbf0e169SBarry Smith 365b4fc646aSLois Curfman McInnes Input Parameter: 366639f9d9dSBarry Smith . c - coloring context 367bbf0e169SBarry Smith 368639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 369bbf0e169SBarry Smith @*/ 370639f9d9dSBarry Smith int MatFDColoringDestroy(MatFDColoring c) 371bbf0e169SBarry Smith { 372639f9d9dSBarry Smith int i,ierr,flag; 373bbf0e169SBarry Smith 374d4bb536fSBarry Smith if (--c->refct > 0) return 0; 375d4bb536fSBarry Smith 376639f9d9dSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-matfdcoloring_view",&flag); 377639f9d9dSBarry Smith if (flag) { 378bbf0e169SBarry Smith Viewer viewer; 379639f9d9dSBarry Smith ierr = ViewerFileOpenASCII(c->comm,"stdout",&viewer);CHKERRQ(ierr); 380639f9d9dSBarry Smith ierr = MatFDColoringView(c,viewer);CHKERRQ(ierr); 381bbf0e169SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 382bbf0e169SBarry Smith } 383639f9d9dSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-matfdcoloring_view_info",&flag); 384639f9d9dSBarry Smith if (flag) { 385bbf0e169SBarry Smith Viewer viewer; 386639f9d9dSBarry Smith ierr = ViewerFileOpenASCII(c->comm,"stdout",&viewer);CHKERRQ(ierr); 387639f9d9dSBarry Smith ierr = ViewerPushFormat(viewer,VIEWER_FORMAT_ASCII_INFO, PETSC_NULL); CHKERRQ(ierr); 388639f9d9dSBarry Smith ierr = MatFDColoringView(c,viewer);CHKERRQ(ierr); 389639f9d9dSBarry Smith ierr = ViewerPopFormat(viewer); 390bbf0e169SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 391bbf0e169SBarry Smith } 392639f9d9dSBarry Smith 393639f9d9dSBarry Smith for ( i=0; i<c->ncolors; i++ ) { 394639f9d9dSBarry Smith if (c->columns[i]) PetscFree(c->columns[i]); 395639f9d9dSBarry Smith if (c->rows[i]) PetscFree(c->rows[i]); 396639f9d9dSBarry Smith if (c->columnsforrow[i]) PetscFree(c->columnsforrow[i]); 397bbf0e169SBarry Smith } 398639f9d9dSBarry Smith PetscFree(c->ncolumns); 399639f9d9dSBarry Smith PetscFree(c->columns); 400639f9d9dSBarry Smith PetscFree(c->nrows); 401639f9d9dSBarry Smith PetscFree(c->rows); 402639f9d9dSBarry Smith PetscFree(c->columnsforrow); 403639f9d9dSBarry Smith PetscFree(c->scale); 404005c665bSBarry Smith if (c->w1) { 405005c665bSBarry Smith ierr = VecDestroy(c->w1); CHKERRQ(ierr); 406005c665bSBarry Smith ierr = VecDestroy(c->w2); CHKERRQ(ierr); 407005c665bSBarry Smith ierr = VecDestroy(c->w3); CHKERRQ(ierr); 408005c665bSBarry Smith } 409639f9d9dSBarry Smith PLogObjectDestroy(c); 410639f9d9dSBarry Smith PetscHeaderDestroy(c); 411bbf0e169SBarry Smith return 0; 412bbf0e169SBarry Smith } 41343a90d84SBarry Smith 414005c665bSBarry Smith #include "snes.h" 415005c665bSBarry Smith 4165615d1e5SSatish Balay #undef __FUNC__ 4175615d1e5SSatish Balay #define __FUNC__ "MatFDColoringApply" 41843a90d84SBarry Smith /*@ 419*e0907662SLois Curfman McInnes MatFDColoringApply - Given a matrix for which a MatFDColoring context 420*e0907662SLois Curfman McInnes has been created, computes the Jacobian for a function via finite differences. 42143a90d84SBarry Smith 42243a90d84SBarry Smith Input Parameters: 42343a90d84SBarry Smith . mat - location to store Jacobian 42443a90d84SBarry Smith . coloring - coloring context created with MatFDColoringCreate() 42543a90d84SBarry Smith . x1 - location at which Jacobian is to be computed 426005c665bSBarry Smith . sctx - optional context required by function (actually a SNES context) 42743a90d84SBarry Smith 42843a90d84SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView() 42943a90d84SBarry Smith 43043a90d84SBarry Smith .keywords: coloring, Jacobian, finite differences 43143a90d84SBarry Smith @*/ 432005c665bSBarry Smith int MatFDColoringApply(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 43343a90d84SBarry Smith { 434*e0907662SLois Curfman McInnes int k,fg,ierr,N,start,end,l,row,col,srow; 43543a90d84SBarry Smith Scalar dx, mone = -1.0,*y,*scale = coloring->scale,*xx,*wscale = coloring->wscale; 43643a90d84SBarry Smith double epsilon = coloring->error_rel, umin = coloring->umin; 43743a90d84SBarry Smith MPI_Comm comm = coloring->comm; 438005c665bSBarry Smith Vec w1,w2,w3; 439dd9fa9a5SLois Curfman McInnes int (*f)(void *,Vec,Vec,void *) = coloring->f; 440005c665bSBarry Smith void *fctx = coloring->fctx; 441005c665bSBarry Smith 442*e0907662SLois Curfman McInnes PetscValidHeaderSpecific(J,MAT_COOKIE); 443*e0907662SLois Curfman McInnes PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_COOKIE); 444*e0907662SLois Curfman McInnes PetscValidHeaderSpecific(x1,VEC_COOKIE); 445*e0907662SLois Curfman McInnes 446d4bb536fSBarry Smith /* 447005c665bSBarry Smith ierr = SNESGetIterationNumber((SNES)sctx,&it); CHKERRQ(ierr); 448005c665bSBarry Smith if ((freq > 1) && ((it % freq) != 1)) { 449005c665bSBarry Smith PLogInfo(coloring,"MatFDColoringApply:Skipping Jacobian, iteration %d, freq %d\n",it,freq); 450005c665bSBarry Smith *flag = SAME_PRECONDITIONER; 451005c665bSBarry Smith return 0; 452005c665bSBarry Smith } else { 453005c665bSBarry Smith PLogInfo(coloring,"MatFDColoringApply:Computing Jacobian, iteration %d, freq %d\n",it,freq); 454005c665bSBarry Smith *flag = SAME_NONZERO_PATTERN; 455d4bb536fSBarry Smith }*/ 456005c665bSBarry Smith 457005c665bSBarry Smith if (!coloring->w1) { 458005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w1); CHKERRQ(ierr); 459005c665bSBarry Smith PLogObjectParent(coloring,coloring->w1); 460005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w2); CHKERRQ(ierr); 461005c665bSBarry Smith PLogObjectParent(coloring,coloring->w2); 462005c665bSBarry Smith ierr = VecDuplicate(x1,&coloring->w3); CHKERRQ(ierr); 463005c665bSBarry Smith PLogObjectParent(coloring,coloring->w3); 464005c665bSBarry Smith } 465005c665bSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 46643a90d84SBarry Smith 467*e0907662SLois Curfman McInnes ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&fg); CHKERRQ(ierr); 468*e0907662SLois Curfman McInnes if (fg) { 469*e0907662SLois Curfman McInnes PLogInfo(coloring,"MatFDColoringApply: Not calling MatZeroEntries()\n"); 470*e0907662SLois Curfman McInnes } else { 47143a90d84SBarry Smith ierr = MatZeroEntries(J); CHKERRQ(ierr); 472*e0907662SLois Curfman McInnes } 47343a90d84SBarry Smith 47443a90d84SBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end); CHKERRQ(ierr); 47543a90d84SBarry Smith ierr = VecGetSize(x1,&N); CHKERRQ(ierr); 47643a90d84SBarry Smith ierr = VecGetArray(x1,&xx); CHKERRQ(ierr); 47743a90d84SBarry Smith ierr = (*f)(sctx,x1,w1,fctx); CHKERRQ(ierr); 47843a90d84SBarry Smith 47943a90d84SBarry Smith PetscMemzero(wscale,N*sizeof(Scalar)); 48043a90d84SBarry Smith /* 48143a90d84SBarry Smith Loop over each color 48243a90d84SBarry Smith */ 48343a90d84SBarry Smith 48443a90d84SBarry Smith for (k=0; k<coloring->ncolors; k++) { 48543a90d84SBarry Smith ierr = VecCopy(x1,w3); CHKERRQ(ierr); 48643a90d84SBarry Smith /* 48743a90d84SBarry Smith Loop over each column associated with color adding the 48843a90d84SBarry Smith perturbation to the vector w3. 48943a90d84SBarry Smith */ 49043a90d84SBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 49143a90d84SBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 49243a90d84SBarry Smith dx = xx[col-start]; 493ae09f205SBarry Smith if (dx == 0.0) dx = 1.0; 49443a90d84SBarry Smith #if !defined(PETSC_COMPLEX) 495ae09f205SBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 496ae09f205SBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 49743a90d84SBarry Smith #else 498ae09f205SBarry Smith if (abs(dx) < umin && real(dx) >= 0.0) dx = umin; 499ae09f205SBarry Smith else if (real(dx) < 0.0 && abs(dx) < umin) dx = -umin; 50043a90d84SBarry Smith #endif 50143a90d84SBarry Smith dx *= epsilon; 50243a90d84SBarry Smith wscale[col] = 1.0/dx; 50343a90d84SBarry Smith VecSetValues(w3,1,&col,&dx,ADD_VALUES); 50443a90d84SBarry Smith } 50543a90d84SBarry Smith VecRestoreArray(x1,&xx); 50643a90d84SBarry Smith /* 507*e0907662SLois Curfman McInnes Evaluate function at x1 + dx (here dx is a vector of perturbations) 50843a90d84SBarry Smith */ 50943a90d84SBarry Smith ierr = (*f)(sctx,w3,w2,fctx); CHKERRQ(ierr); 51043a90d84SBarry Smith ierr = VecAXPY(&mone,w1,w2); CHKERRQ(ierr); 51143a90d84SBarry Smith /* Communicate scale to all processors */ 51243a90d84SBarry Smith #if !defined(PETSC_COMPLEX) 51343a90d84SBarry Smith MPI_Allreduce(wscale,scale,N,MPI_DOUBLE,MPI_SUM,comm); 51443a90d84SBarry Smith #else 51543a90d84SBarry Smith MPI_Allreduce(wscale,scale,2*N,MPI_DOUBLE,MPI_SUM,comm); 51643a90d84SBarry Smith #endif 51743a90d84SBarry Smith /* 518*e0907662SLois Curfman McInnes Loop over rows of vector, putting results into Jacobian matrix 51943a90d84SBarry Smith */ 52043a90d84SBarry Smith VecGetArray(w2,&y); 52143a90d84SBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 52243a90d84SBarry Smith row = coloring->rows[k][l]; 52343a90d84SBarry Smith col = coloring->columnsforrow[k][l]; 52443a90d84SBarry Smith y[row] *= scale[col]; 52543a90d84SBarry Smith srow = row + start; 52643a90d84SBarry Smith ierr = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 52743a90d84SBarry Smith } 52843a90d84SBarry Smith VecRestoreArray(w2,&y); 52943a90d84SBarry Smith } 53043a90d84SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 53143a90d84SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 53243a90d84SBarry Smith return 0; 53343a90d84SBarry Smith } 534