1be1d678aSKris Buschelman 2bbf0e169SBarry Smith /* 3639f9d9dSBarry Smith This is where the abstract matrix operations are defined that are 4639f9d9dSBarry Smith used for finite difference computations of Jacobians using coloring. 5bbf0e169SBarry Smith */ 6bbf0e169SBarry Smith 7b45d2f2cSJed Brown #include <petsc-private/matimpl.h> /*I "petscmat.h" I*/ 8bbf0e169SBarry Smith 94a2ae208SSatish Balay #undef __FUNCT__ 103a7fca6bSBarry Smith #define __FUNCT__ "MatFDColoringSetF" 117087cfbeSBarry Smith PetscErrorCode MatFDColoringSetF(MatFDColoring fd,Vec F) 123a7fca6bSBarry Smith { 134e269d77SPeter Brune PetscErrorCode ierr; 143a7fca6bSBarry Smith PetscFunctionBegin; 154e269d77SPeter Brune if (F) { 164e269d77SPeter Brune ierr = VecCopy(F,fd->w1);CHKERRQ(ierr); 174e269d77SPeter Brune fd->fset = PETSC_TRUE; 184e269d77SPeter Brune } else { 194e269d77SPeter Brune fd->fset = PETSC_FALSE; 204e269d77SPeter Brune } 213a7fca6bSBarry Smith PetscFunctionReturn(0); 223a7fca6bSBarry Smith } 233a7fca6bSBarry Smith 243a7fca6bSBarry Smith #undef __FUNCT__ 254a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringView_Draw_Zoom" 266849ba73SBarry Smith static PetscErrorCode MatFDColoringView_Draw_Zoom(PetscDraw draw,void *Aa) 279194eea9SBarry Smith { 289194eea9SBarry Smith MatFDColoring fd = (MatFDColoring)Aa; 29dfbe8321SBarry Smith PetscErrorCode ierr; 3038baddfdSBarry Smith PetscInt i,j; 319194eea9SBarry Smith PetscReal x,y; 329194eea9SBarry Smith 339194eea9SBarry Smith PetscFunctionBegin; 349194eea9SBarry Smith 359194eea9SBarry Smith /* loop over colors */ 369194eea9SBarry Smith for (i=0; i<fd->ncolors; i++) { 379194eea9SBarry Smith for (j=0; j<fd->nrows[i]; j++) { 389194eea9SBarry Smith y = fd->M - fd->rows[i][j] - fd->rstart; 399194eea9SBarry Smith x = fd->columnsforrow[i][j]; 40b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1);CHKERRQ(ierr); 419194eea9SBarry Smith } 429194eea9SBarry Smith } 439194eea9SBarry Smith PetscFunctionReturn(0); 449194eea9SBarry Smith } 459194eea9SBarry Smith 464a2ae208SSatish Balay #undef __FUNCT__ 474a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringView_Draw" 486849ba73SBarry Smith static PetscErrorCode MatFDColoringView_Draw(MatFDColoring fd,PetscViewer viewer) 49005c665bSBarry Smith { 50dfbe8321SBarry Smith PetscErrorCode ierr; 51ace3abfcSBarry Smith PetscBool isnull; 52b0a32e0cSBarry Smith PetscDraw draw; 5354d96fa3SBarry Smith PetscReal xr,yr,xl,yl,h,w; 54005c665bSBarry Smith 553a40ed3dSBarry Smith PetscFunctionBegin; 56b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 57b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 589194eea9SBarry Smith 599194eea9SBarry Smith ierr = PetscObjectCompose((PetscObject)fd,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 60005c665bSBarry Smith 61005c665bSBarry Smith xr = fd->N; yr = fd->M; h = yr/10.0; w = xr/10.0; 62005c665bSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 63b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 64b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatFDColoringView_Draw_Zoom,fd);CHKERRQ(ierr); 659194eea9SBarry Smith ierr = PetscObjectCompose((PetscObject)fd,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 663a40ed3dSBarry Smith PetscFunctionReturn(0); 67005c665bSBarry Smith } 68005c665bSBarry Smith 694a2ae208SSatish Balay #undef __FUNCT__ 704a2ae208SSatish Balay #define __FUNCT__ "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 84b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 85b0a32e0cSBarry Smith . PETSC_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. 89b0a32e0cSBarry Smith - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 90bbf0e169SBarry Smith 919194eea9SBarry Smith Notes: 929194eea9SBarry Smith Since PETSc uses only a small number of basic colors (currently 33), if the coloring 93b0a32e0cSBarry Smith involves more than 33 then some seemingly identical colors are displayed making it look 949194eea9SBarry Smith like an illegal coloring. This is just a graphical artifact. 959194eea9SBarry Smith 96639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 97005c665bSBarry Smith 98b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, view 99bbf0e169SBarry Smith @*/ 1007087cfbeSBarry Smith PetscErrorCode MatFDColoringView(MatFDColoring c,PetscViewer viewer) 101bbf0e169SBarry Smith { 1026849ba73SBarry Smith PetscErrorCode ierr; 10338baddfdSBarry Smith PetscInt i,j; 104ace3abfcSBarry Smith PetscBool isdraw,iascii; 105f3ef73ceSBarry Smith PetscViewerFormat format; 106bbf0e169SBarry Smith 1073a40ed3dSBarry Smith PetscFunctionBegin; 1080700a824SBarry Smith PetscValidHeaderSpecific(c,MAT_FDCOLORING_CLASSID,1); 1093050cee2SBarry Smith if (!viewer) { 1107adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)c)->comm,&viewer);CHKERRQ(ierr); 1113050cee2SBarry Smith } 1120700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 113c9780b6fSBarry Smith PetscCheckSameComm(c,1,viewer,2); 114bbf0e169SBarry Smith 115251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 116251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1170f5bd95cSBarry Smith if (isdraw) { 118b4fc646aSLois Curfman McInnes ierr = MatFDColoringView_Draw(c,viewer);CHKERRQ(ierr); 11932077d6dSBarry Smith } else if (iascii) { 120317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)c,viewer,"MatFDColoring Object");CHKERRQ(ierr); 121a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Error tolerance=%G\n",c->error_rel);CHKERRQ(ierr); 122a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Umin=%G\n",c->umin);CHKERRQ(ierr); 12377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Number of colors=%D\n",c->ncolors);CHKERRQ(ierr); 124ae09f205SBarry Smith 125b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 126fb9695e5SSatish Balay if (format != PETSC_VIEWER_ASCII_INFO) { 127b4fc646aSLois Curfman McInnes for (i=0; i<c->ncolors; i++) { 12877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Information for color %D\n",i);CHKERRQ(ierr); 12977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Number of columns %D\n",c->ncolumns[i]);CHKERRQ(ierr); 130b4fc646aSLois Curfman McInnes for (j=0; j<c->ncolumns[i]; j++) { 13177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D\n",c->columns[i][j]);CHKERRQ(ierr); 132639f9d9dSBarry Smith } 13377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Number of rows %D\n",c->nrows[i]);CHKERRQ(ierr); 134b4fc646aSLois Curfman McInnes for (j=0; j<c->nrows[i]; j++) { 13577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D \n",c->rows[i][j],c->columnsforrow[i][j]);CHKERRQ(ierr); 136b4fc646aSLois Curfman McInnes } 137bbf0e169SBarry Smith } 138bbf0e169SBarry Smith } 139b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1405cd90555SBarry Smith } else { 141e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for MatFDColoring",((PetscObject)viewer)->type_name); 142bbf0e169SBarry Smith } 1433a40ed3dSBarry Smith PetscFunctionReturn(0); 144639f9d9dSBarry Smith } 145639f9d9dSBarry Smith 1464a2ae208SSatish Balay #undef __FUNCT__ 1474a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringSetParameters" 148639f9d9dSBarry Smith /*@ 149b4fc646aSLois Curfman McInnes MatFDColoringSetParameters - Sets the parameters for the sparse approximation of 150b4fc646aSLois Curfman McInnes a Jacobian matrix using finite differences. 151639f9d9dSBarry Smith 1523f9fe445SBarry Smith Logically Collective on MatFDColoring 153ef5ee4d1SLois Curfman McInnes 154ef5ee4d1SLois Curfman McInnes The Jacobian is estimated with the differencing approximation 155ef5ee4d1SLois Curfman McInnes .vb 15665f2ba5bSLois Curfman McInnes F'(u)_{:,i} = [F(u+h*dx_{i}) - F(u)]/h where 157f23b5b22SLois Curfman McInnes h = error_rel*u[i] if abs(u[i]) > umin 158f23b5b22SLois Curfman McInnes = +/- error_rel*umin otherwise, with +/- determined by the sign of u[i] 159ef5ee4d1SLois Curfman McInnes dx_{i} = (0, ... 1, .... 0) 160ef5ee4d1SLois Curfman McInnes .ve 161639f9d9dSBarry Smith 162639f9d9dSBarry Smith Input Parameters: 163ef5ee4d1SLois Curfman McInnes + coloring - the coloring context 164639f9d9dSBarry Smith . error_rel - relative error 165f23b5b22SLois Curfman McInnes - umin - minimum allowable u-value magnitude 166fee21e36SBarry Smith 16715091d37SBarry Smith Level: advanced 16815091d37SBarry Smith 169b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, parameters 170b4fc646aSLois Curfman McInnes 17195b89fc3SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringSetFromOptions() 17295b89fc3SBarry Smith 173639f9d9dSBarry Smith @*/ 1747087cfbeSBarry Smith PetscErrorCode MatFDColoringSetParameters(MatFDColoring matfd,PetscReal error,PetscReal umin) 175639f9d9dSBarry Smith { 1763a40ed3dSBarry Smith PetscFunctionBegin; 1770700a824SBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 178c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(matfd,error,2); 179c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(matfd,umin,3); 180639f9d9dSBarry Smith if (error != PETSC_DEFAULT) matfd->error_rel = error; 181639f9d9dSBarry Smith if (umin != PETSC_DEFAULT) matfd->umin = umin; 1823a40ed3dSBarry Smith PetscFunctionReturn(0); 183639f9d9dSBarry Smith } 184639f9d9dSBarry Smith 185005c665bSBarry Smith 186ff0cfa39SBarry Smith 1874a2ae208SSatish Balay #undef __FUNCT__ 1884a9d489dSBarry Smith #define __FUNCT__ "MatFDColoringGetFunction" 1894a9d489dSBarry Smith /*@C 1904a9d489dSBarry Smith MatFDColoringGetFunction - Gets the function to use for computing the Jacobian. 1914a9d489dSBarry Smith 1923f9fe445SBarry Smith Not Collective 1934a9d489dSBarry Smith 1944a9d489dSBarry Smith Input Parameters: 1954a9d489dSBarry Smith . coloring - the coloring context 1964a9d489dSBarry Smith 1974a9d489dSBarry Smith Output Parameters: 1984a9d489dSBarry Smith + f - the function 1994a9d489dSBarry Smith - fctx - the optional user-defined function context 2004a9d489dSBarry Smith 2014a9d489dSBarry Smith Level: intermediate 2024a9d489dSBarry Smith 2034a9d489dSBarry Smith .keywords: Mat, Jacobian, finite differences, set, function 20495b89fc3SBarry Smith 20595b89fc3SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringSetFunction(), MatFDColoringSetFromOptions() 20695b89fc3SBarry Smith 2074a9d489dSBarry Smith @*/ 2087087cfbeSBarry Smith PetscErrorCode MatFDColoringGetFunction(MatFDColoring matfd,PetscErrorCode (**f)(void),void **fctx) 2094a9d489dSBarry Smith { 2104a9d489dSBarry Smith PetscFunctionBegin; 2110700a824SBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 2124a9d489dSBarry Smith if (f) *f = matfd->f; 2134a9d489dSBarry Smith if (fctx) *fctx = matfd->fctx; 2144a9d489dSBarry Smith PetscFunctionReturn(0); 2154a9d489dSBarry Smith } 2164a9d489dSBarry Smith 2174a9d489dSBarry Smith #undef __FUNCT__ 2184a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringSetFunction" 219d64ed03dSBarry Smith /*@C 220005c665bSBarry Smith MatFDColoringSetFunction - Sets the function to use for computing the Jacobian. 221005c665bSBarry Smith 2223f9fe445SBarry Smith Logically Collective on MatFDColoring 223fee21e36SBarry Smith 224ef5ee4d1SLois Curfman McInnes Input Parameters: 225ef5ee4d1SLois Curfman McInnes + coloring - the coloring context 226ef5ee4d1SLois Curfman McInnes . f - the function 227ef5ee4d1SLois Curfman McInnes - fctx - the optional user-defined function context 228ef5ee4d1SLois Curfman McInnes 2297850c7c0SBarry Smith Calling sequence of (*f) function: 2307850c7c0SBarry Smith For SNES: PetscErrorCode (*f)(SNES,Vec,Vec,void*) 231ab637aeaSJed Brown If not using SNES: PetscErrorCode (*f)(void *dummy,Vec,Vec,void*) and dummy is ignored 23215091d37SBarry Smith 2337850c7c0SBarry Smith Level: advanced 2347850c7c0SBarry Smith 235ab637aeaSJed Brown Notes: This function is usually used automatically by SNES (when one uses SNESSetJacobian() with the argument 236ab637aeaSJed Brown SNESDefaultComputeJacobianColor()) and only needs to be used by someone computing a matrix via coloring directly by 237ab637aeaSJed Brown calling MatFDColoringApply() 2387850c7c0SBarry Smith 2397850c7c0SBarry Smith Fortran Notes: 2407850c7c0SBarry Smith In Fortran you must call MatFDColoringSetFunction() for a coloring object to 241ab637aeaSJed Brown be used without SNES or within the SNES solvers. 242f881d145SBarry Smith 243b4fc646aSLois Curfman McInnes .keywords: Mat, Jacobian, finite differences, set, function 24495b89fc3SBarry Smith 24595b89fc3SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringGetFunction(), MatFDColoringSetFromOptions() 24695b89fc3SBarry Smith 247005c665bSBarry Smith @*/ 2487087cfbeSBarry Smith PetscErrorCode MatFDColoringSetFunction(MatFDColoring matfd,PetscErrorCode (*f)(void),void *fctx) 249005c665bSBarry Smith { 2503a40ed3dSBarry Smith PetscFunctionBegin; 2510700a824SBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 252005c665bSBarry Smith matfd->f = f; 253005c665bSBarry Smith matfd->fctx = fctx; 2543a40ed3dSBarry Smith PetscFunctionReturn(0); 255005c665bSBarry Smith } 256005c665bSBarry Smith 2574a2ae208SSatish Balay #undef __FUNCT__ 2584a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringSetFromOptions" 259639f9d9dSBarry Smith /*@ 260b4fc646aSLois Curfman McInnes MatFDColoringSetFromOptions - Sets coloring finite difference parameters from 261639f9d9dSBarry Smith the options database. 262639f9d9dSBarry Smith 263fee21e36SBarry Smith Collective on MatFDColoring 264fee21e36SBarry Smith 26565f2ba5bSLois Curfman McInnes The Jacobian, F'(u), is estimated with the differencing approximation 266ef5ee4d1SLois Curfman McInnes .vb 26765f2ba5bSLois Curfman McInnes F'(u)_{:,i} = [F(u+h*dx_{i}) - F(u)]/h where 268f23b5b22SLois Curfman McInnes h = error_rel*u[i] if abs(u[i]) > umin 269f23b5b22SLois Curfman McInnes = +/- error_rel*umin otherwise, with +/- determined by the sign of u[i] 270ef5ee4d1SLois Curfman McInnes dx_{i} = (0, ... 1, .... 0) 271ef5ee4d1SLois Curfman McInnes .ve 272ef5ee4d1SLois Curfman McInnes 273ef5ee4d1SLois Curfman McInnes Input Parameter: 274ef5ee4d1SLois Curfman McInnes . coloring - the coloring context 275ef5ee4d1SLois Curfman McInnes 276b4fc646aSLois Curfman McInnes Options Database Keys: 277d15ffeeaSSatish Balay + -mat_fd_coloring_err <err> - Sets <err> (square root 278ef5ee4d1SLois Curfman McInnes of relative error in the function) 279f23b5b22SLois Curfman McInnes . -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude 2803ec795f1SBarry Smith . -mat_fd_type - "wp" or "ds" (see MATMFFD_WP or MATMFFD_DS) 281ef5ee4d1SLois Curfman McInnes . -mat_fd_coloring_view - Activates basic viewing 282*e350db43SBarry Smith . -mat_fd_coloring_view ::ascii_info - Activates viewing info 283*e350db43SBarry Smith - -mat_fd_coloring_view draw - Activates drawing 284639f9d9dSBarry Smith 28515091d37SBarry Smith Level: intermediate 28615091d37SBarry Smith 287b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, parameters 288d1c39f55SBarry Smith 289d1c39f55SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringView(), MatFDColoringSetParameters() 290d1c39f55SBarry Smith 291639f9d9dSBarry Smith @*/ 2927087cfbeSBarry Smith PetscErrorCode MatFDColoringSetFromOptions(MatFDColoring matfd) 293639f9d9dSBarry Smith { 294dfbe8321SBarry Smith PetscErrorCode ierr; 295ace3abfcSBarry Smith PetscBool flg; 296efb30889SBarry Smith char value[3]; 2973a40ed3dSBarry Smith 2983a40ed3dSBarry Smith PetscFunctionBegin; 2990700a824SBarry Smith PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1); 300639f9d9dSBarry Smith 3013194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)matfd);CHKERRQ(ierr); 30287828ca2SBarry Smith ierr = PetscOptionsReal("-mat_fd_coloring_err","Square root of relative error in function","MatFDColoringSetParameters",matfd->error_rel,&matfd->error_rel,0);CHKERRQ(ierr); 30387828ca2SBarry Smith ierr = PetscOptionsReal("-mat_fd_coloring_umin","Minimum allowable u magnitude","MatFDColoringSetParameters",matfd->umin,&matfd->umin,0);CHKERRQ(ierr); 3041bc75a8dSBarry Smith ierr = PetscOptionsString("-mat_fd_type","Algorithm to compute h, wp or ds","MatFDColoringCreate",matfd->htype,value,3,&flg);CHKERRQ(ierr); 305efb30889SBarry Smith if (flg) { 306efb30889SBarry Smith if (value[0] == 'w' && value[1] == 'p') matfd->htype = "wp"; 307efb30889SBarry Smith else if (value[0] == 'd' && value[1] == 's') matfd->htype = "ds"; 308e32f2f54SBarry Smith else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown finite differencing type %s",value); 309efb30889SBarry Smith } 3105d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 3115d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)matfd);CHKERRQ(ierr); 312b0a32e0cSBarry Smith PetscOptionsEnd();CHKERRQ(ierr); 3133a40ed3dSBarry Smith PetscFunctionReturn(0); 314005c665bSBarry Smith } 315005c665bSBarry Smith 3164a2ae208SSatish Balay #undef __FUNCT__ 317*e350db43SBarry Smith #define __FUNCT__ "MatFDColoringViewFromOptions" 318*e350db43SBarry Smith PetscErrorCode MatFDColoringViewFromOptions(MatFDColoring fd,const char optionname[]) 319005c665bSBarry Smith { 320dfbe8321SBarry Smith PetscErrorCode ierr; 321*e350db43SBarry Smith PetscBool flg; 3223050cee2SBarry Smith PetscViewer viewer; 323005c665bSBarry Smith 3243a40ed3dSBarry Smith PetscFunctionBegin; 325*e350db43SBarry Smith ierr = PetscOptionsGetViewer(((PetscObject)fd)->comm,((PetscObject)fd)->prefix,optionname,&viewer,&flg);CHKERRQ(ierr); 326005c665bSBarry Smith if (flg) { 3273050cee2SBarry Smith ierr = MatFDColoringView(fd,viewer);CHKERRQ(ierr); 328*e350db43SBarry Smith ierr = PetscOptionsRestoreViewer(viewer);CHKERRQ(ierr); 329005c665bSBarry Smith } 3303a40ed3dSBarry Smith PetscFunctionReturn(0); 331bbf0e169SBarry Smith } 332bbf0e169SBarry Smith 3334a2ae208SSatish Balay #undef __FUNCT__ 3344a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate" 33505869f15SSatish Balay /*@ 336639f9d9dSBarry Smith MatFDColoringCreate - Creates a matrix coloring context for finite difference 337639f9d9dSBarry Smith computation of Jacobians. 338bbf0e169SBarry Smith 339ef5ee4d1SLois Curfman McInnes Collective on Mat 340ef5ee4d1SLois Curfman McInnes 341639f9d9dSBarry Smith Input Parameters: 342ef5ee4d1SLois Curfman McInnes + mat - the matrix containing the nonzero structure of the Jacobian 343e727c939SJed Brown - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring() 344bbf0e169SBarry Smith 345bbf0e169SBarry Smith Output Parameter: 346639f9d9dSBarry Smith . color - the new coloring context 347bbf0e169SBarry Smith 34815091d37SBarry Smith Level: intermediate 34915091d37SBarry Smith 3506831982aSBarry Smith .seealso: MatFDColoringDestroy(),SNESDefaultComputeJacobianColor(), ISColoringCreate(), 351d1c39f55SBarry Smith MatFDColoringSetFunction(), MatFDColoringSetFromOptions(), MatFDColoringApply(), 352e727c939SJed Brown MatFDColoringView(), MatFDColoringSetParameters(), MatGetColoring(), DMCreateColoring() 353bbf0e169SBarry Smith @*/ 3547087cfbeSBarry Smith PetscErrorCode MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color) 355bbf0e169SBarry Smith { 356639f9d9dSBarry Smith MatFDColoring c; 357639f9d9dSBarry Smith MPI_Comm comm; 358dfbe8321SBarry Smith PetscErrorCode ierr; 35938baddfdSBarry Smith PetscInt M,N; 360639f9d9dSBarry Smith 3613a40ed3dSBarry Smith PetscFunctionBegin; 362d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(MAT_FDColoringCreate,mat,0,0,0);CHKERRQ(ierr); 363639f9d9dSBarry Smith ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 36417186662SBarry Smith if (M != N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Only for square matrices"); 365f881d145SBarry Smith ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3663194b578SJed Brown ierr = PetscHeaderCreate(c,_p_MatFDColoring,int,MAT_FDCOLORING_CLASSID,0,"MatFDColoring","Jacobian computation via finite differences with coloring","Mat",comm,MatFDColoringDestroy,MatFDColoringView);CHKERRQ(ierr); 367639f9d9dSBarry Smith 368b8f8c88eSHong Zhang c->ctype = iscoloring->ctype; 369b8f8c88eSHong Zhang 370f830108cSBarry Smith if (mat->ops->fdcoloringcreate) { 371f830108cSBarry Smith ierr = (*mat->ops->fdcoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 372577b14d0SJed Brown } else SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 373639f9d9dSBarry Smith 374b8f8c88eSHong Zhang ierr = MatGetVecs(mat,PETSC_NULL,&c->w1);CHKERRQ(ierr); 375b8f8c88eSHong Zhang ierr = PetscLogObjectParent(c,c->w1);CHKERRQ(ierr); 376b8f8c88eSHong Zhang ierr = VecDuplicate(c->w1,&c->w2);CHKERRQ(ierr); 377b8f8c88eSHong Zhang ierr = PetscLogObjectParent(c,c->w2);CHKERRQ(ierr); 378b8f8c88eSHong Zhang 37977d8c4bbSBarry Smith c->error_rel = PETSC_SQRT_MACHINE_EPSILON; 38077d8c4bbSBarry Smith c->umin = 100.0*PETSC_SQRT_MACHINE_EPSILON; 38149b058dcSBarry Smith c->currentcolor = -1; 382efb30889SBarry Smith c->htype = "wp"; 3834e269d77SPeter Brune c->fset = PETSC_FALSE; 384639f9d9dSBarry Smith 385639f9d9dSBarry Smith *color = c; 3864e269d77SPeter Brune ierr = PetscObjectCompose((PetscObject)mat,"SNESMatFDColoring",(PetscObject)c);CHKERRQ(ierr); 387d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(MAT_FDColoringCreate,mat,0,0,0);CHKERRQ(ierr); 3883a40ed3dSBarry Smith PetscFunctionReturn(0); 389bbf0e169SBarry Smith } 390bbf0e169SBarry Smith 3914a2ae208SSatish Balay #undef __FUNCT__ 3924a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringDestroy" 39305869f15SSatish Balay /*@ 394639f9d9dSBarry Smith MatFDColoringDestroy - Destroys a matrix coloring context that was created 395639f9d9dSBarry Smith via MatFDColoringCreate(). 396bbf0e169SBarry Smith 397ef5ee4d1SLois Curfman McInnes Collective on MatFDColoring 398ef5ee4d1SLois Curfman McInnes 399b4fc646aSLois Curfman McInnes Input Parameter: 400639f9d9dSBarry Smith . c - coloring context 401bbf0e169SBarry Smith 40215091d37SBarry Smith Level: intermediate 40315091d37SBarry Smith 404639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 405bbf0e169SBarry Smith @*/ 4066bf464f9SBarry Smith PetscErrorCode MatFDColoringDestroy(MatFDColoring *c) 407bbf0e169SBarry Smith { 4086849ba73SBarry Smith PetscErrorCode ierr; 40938baddfdSBarry Smith PetscInt i; 410bbf0e169SBarry Smith 4113a40ed3dSBarry Smith PetscFunctionBegin; 4126bf464f9SBarry Smith if (!*c) PetscFunctionReturn(0); 4136bf464f9SBarry Smith if (--((PetscObject)(*c))->refct > 0) {*c = 0; PetscFunctionReturn(0);} 414d4bb536fSBarry Smith 4156bf464f9SBarry Smith for (i=0; i<(*c)->ncolors; i++) { 4166bf464f9SBarry Smith ierr = PetscFree((*c)->columns[i]);CHKERRQ(ierr); 4176bf464f9SBarry Smith ierr = PetscFree((*c)->rows[i]);CHKERRQ(ierr); 4186bf464f9SBarry Smith ierr = PetscFree((*c)->columnsforrow[i]);CHKERRQ(ierr); 4196bf464f9SBarry Smith if ((*c)->vscaleforrow) {ierr = PetscFree((*c)->vscaleforrow[i]);CHKERRQ(ierr);} 420bbf0e169SBarry Smith } 4216bf464f9SBarry Smith ierr = PetscFree((*c)->ncolumns);CHKERRQ(ierr); 4226bf464f9SBarry Smith ierr = PetscFree((*c)->columns);CHKERRQ(ierr); 4236bf464f9SBarry Smith ierr = PetscFree((*c)->nrows);CHKERRQ(ierr); 4246bf464f9SBarry Smith ierr = PetscFree((*c)->rows);CHKERRQ(ierr); 4256bf464f9SBarry Smith ierr = PetscFree((*c)->columnsforrow);CHKERRQ(ierr); 4266bf464f9SBarry Smith ierr = PetscFree((*c)->vscaleforrow);CHKERRQ(ierr); 4276bf464f9SBarry Smith ierr = VecDestroy(&(*c)->vscale);CHKERRQ(ierr); 4286bf464f9SBarry Smith ierr = VecDestroy(&(*c)->w1);CHKERRQ(ierr); 4296bf464f9SBarry Smith ierr = VecDestroy(&(*c)->w2);CHKERRQ(ierr); 4306bf464f9SBarry Smith ierr = VecDestroy(&(*c)->w3);CHKERRQ(ierr); 431d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 4323a40ed3dSBarry Smith PetscFunctionReturn(0); 433bbf0e169SBarry Smith } 43443a90d84SBarry Smith 4354a2ae208SSatish Balay #undef __FUNCT__ 43649b058dcSBarry Smith #define __FUNCT__ "MatFDColoringGetPerturbedColumns" 43749b058dcSBarry Smith /*@C 43849b058dcSBarry Smith MatFDColoringGetPerturbedColumns - Returns the indices of the columns that 43949b058dcSBarry Smith that are currently being perturbed. 44049b058dcSBarry Smith 44149b058dcSBarry Smith Not Collective 44249b058dcSBarry Smith 44349b058dcSBarry Smith Input Parameters: 44449b058dcSBarry Smith . coloring - coloring context created with MatFDColoringCreate() 44549b058dcSBarry Smith 44649b058dcSBarry Smith Output Parameters: 44749b058dcSBarry Smith + n - the number of local columns being perturbed 44849b058dcSBarry Smith - cols - the column indices, in global numbering 44949b058dcSBarry Smith 45049b058dcSBarry Smith Level: intermediate 45149b058dcSBarry Smith 45249b058dcSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView(), MatFDColoringApply() 45349b058dcSBarry Smith 45449b058dcSBarry Smith .keywords: coloring, Jacobian, finite differences 45549b058dcSBarry Smith @*/ 4567087cfbeSBarry Smith PetscErrorCode MatFDColoringGetPerturbedColumns(MatFDColoring coloring,PetscInt *n,PetscInt *cols[]) 45749b058dcSBarry Smith { 45849b058dcSBarry Smith PetscFunctionBegin; 45949b058dcSBarry Smith if (coloring->currentcolor >= 0) { 46049b058dcSBarry Smith *n = coloring->ncolumns[coloring->currentcolor]; 46149b058dcSBarry Smith *cols = coloring->columns[coloring->currentcolor]; 46249b058dcSBarry Smith } else { 46349b058dcSBarry Smith *n = 0; 46449b058dcSBarry Smith } 46549b058dcSBarry Smith PetscFunctionReturn(0); 46649b058dcSBarry Smith } 46749b058dcSBarry Smith 46849b058dcSBarry Smith #undef __FUNCT__ 4694a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringApply" 47043a90d84SBarry Smith /*@ 471e0907662SLois Curfman McInnes MatFDColoringApply - Given a matrix for which a MatFDColoring context 472e0907662SLois Curfman McInnes has been created, computes the Jacobian for a function via finite differences. 47343a90d84SBarry Smith 474fee21e36SBarry Smith Collective on MatFDColoring 475fee21e36SBarry Smith 476ef5ee4d1SLois Curfman McInnes Input Parameters: 477ef5ee4d1SLois Curfman McInnes + mat - location to store Jacobian 478ef5ee4d1SLois Curfman McInnes . coloring - coloring context created with MatFDColoringCreate() 479ef5ee4d1SLois Curfman McInnes . x1 - location at which Jacobian is to be computed 4807850c7c0SBarry Smith - sctx - context required by function, if this is being used with the SNES solver then it is SNES object, otherwise it is null 481ef5ee4d1SLois Curfman McInnes 4828bba8e72SBarry Smith Options Database Keys: 483ebd3b9afSBarry Smith + -mat_fd_type - "wp" or "ds" (see MATMFFD_WP or MATMFFD_DS) 484b9722508SLois Curfman McInnes . -mat_fd_coloring_view - Activates basic viewing or coloring 485*e350db43SBarry Smith . -mat_fd_coloring_view draw - Activates drawing of coloring 486*e350db43SBarry Smith - -mat_fd_coloring_view ::ascii_info - Activates viewing of coloring info 4878bba8e72SBarry Smith 48815091d37SBarry Smith Level: intermediate 48998d79826SSatish Balay 4907850c7c0SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView(), MatFDColoringSetFunction() 49143a90d84SBarry Smith 49243a90d84SBarry Smith .keywords: coloring, Jacobian, finite differences 49343a90d84SBarry Smith @*/ 4947087cfbeSBarry Smith PetscErrorCode MatFDColoringApply(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 49543a90d84SBarry Smith { 4963acb8795SBarry Smith PetscErrorCode ierr; 4973acb8795SBarry Smith 4983acb8795SBarry Smith PetscFunctionBegin; 4990700a824SBarry Smith PetscValidHeaderSpecific(J,MAT_CLASSID,1); 5000700a824SBarry Smith PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_CLASSID,2); 5010700a824SBarry Smith PetscValidHeaderSpecific(x1,VEC_CLASSID,3); 50217186662SBarry Smith if (!coloring->f) SETERRQ(((PetscObject)J)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetFunction()"); 503e32f2f54SBarry Smith if (!J->ops->fdcoloringapply) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)J)->type_name); 5043acb8795SBarry Smith ierr = (*J->ops->fdcoloringapply)(J,coloring,x1,flag,sctx);CHKERRQ(ierr); 5053acb8795SBarry Smith PetscFunctionReturn(0); 5063acb8795SBarry Smith } 5073acb8795SBarry Smith 5083acb8795SBarry Smith #undef __FUNCT__ 5093acb8795SBarry Smith #define __FUNCT__ "MatFDColoringApply_AIJ" 5107087cfbeSBarry Smith PetscErrorCode MatFDColoringApply_AIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 5113acb8795SBarry Smith { 5126849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 5136849ba73SBarry Smith PetscErrorCode ierr; 5144e269d77SPeter Brune PetscInt k,start,end,l,row,col,srow,**vscaleforrow; 515efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 516ea709b57SSatish Balay PetscScalar *vscale_array; 517efb30889SBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin,unorm; 518b8f8c88eSHong Zhang Vec w1=coloring->w1,w2=coloring->w2,w3; 519005c665bSBarry Smith void *fctx = coloring->fctx; 520ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 521705d48f7SSatish Balay PetscInt ctype=coloring->ctype,N,col_start=0,col_end=0; 522b8f8c88eSHong Zhang Vec x1_tmp; 523a2e34c3dSBarry Smith 5243a40ed3dSBarry Smith PetscFunctionBegin; 5250700a824SBarry Smith PetscValidHeaderSpecific(J,MAT_CLASSID,1); 5260700a824SBarry Smith PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_CLASSID,2); 5270700a824SBarry Smith PetscValidHeaderSpecific(x1,VEC_CLASSID,3); 52817186662SBarry Smith if (!f) SETERRQ(((PetscObject)J)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetFunction()"); 529e0907662SLois Curfman McInnes 530d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr); 5314c49b128SBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 532acfcf0e5SJed Brown ierr = PetscOptionsGetBool(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr); 533f1af5d2fSBarry Smith if (flg) { 534ae15b995SBarry Smith ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 535e0907662SLois Curfman McInnes } else { 536ace3abfcSBarry Smith PetscBool assembled; 5370b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 5380b9b6f31SBarry Smith if (assembled) { 53943a90d84SBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 540e0907662SLois Curfman McInnes } 5410b9b6f31SBarry Smith } 54243a90d84SBarry Smith 543b8f8c88eSHong Zhang x1_tmp = x1; 544dac7f5fdSBarry Smith if (!coloring->vscale){ 545b8f8c88eSHong Zhang ierr = VecDuplicate(x1_tmp,&coloring->vscale);CHKERRQ(ierr); 546b8f8c88eSHong Zhang } 547be2fbe1fSBarry Smith 548b8f8c88eSHong Zhang if (coloring->htype[0] == 'w') { /* tacky test; need to make systematic if we add other approaches to computing h*/ 549b8f8c88eSHong Zhang ierr = VecNorm(x1_tmp,NORM_2,&unorm);CHKERRQ(ierr); 550b8f8c88eSHong Zhang } 551b8f8c88eSHong Zhang ierr = VecGetOwnershipRange(w1,&start,&end);CHKERRQ(ierr); /* OwnershipRange is used by ghosted x! */ 552b8f8c88eSHong Zhang 553b8f8c88eSHong Zhang /* Set w1 = F(x1) */ 5544e269d77SPeter Brune if (!coloring->fset) { 55566f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 556b8f8c88eSHong Zhang ierr = (*f)(sctx,x1_tmp,w1,fctx);CHKERRQ(ierr); 55766f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 5584e269d77SPeter Brune } else { 5594e269d77SPeter Brune coloring->fset = PETSC_FALSE; 560be2fbe1fSBarry Smith } 56143a90d84SBarry Smith 562b8f8c88eSHong Zhang if (!coloring->w3) { 563b8f8c88eSHong Zhang ierr = VecDuplicate(x1_tmp,&coloring->w3);CHKERRQ(ierr); 564b8f8c88eSHong Zhang ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 565efb30889SBarry Smith } 566b8f8c88eSHong Zhang w3 = coloring->w3; 567efb30889SBarry Smith 568b8f8c88eSHong Zhang /* Compute all the local scale factors, including ghost points */ 569b8f8c88eSHong Zhang ierr = VecGetLocalSize(x1_tmp,&N);CHKERRQ(ierr); 570b8f8c88eSHong Zhang ierr = VecGetArray(x1_tmp,&xx);CHKERRQ(ierr); 571b8f8c88eSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 572b8f8c88eSHong Zhang if (ctype == IS_COLORING_GHOSTED){ 573b8f8c88eSHong Zhang col_start = 0; col_end = N; 5748ee2e534SBarry Smith } else if (ctype == IS_COLORING_GLOBAL){ 575b8f8c88eSHong Zhang xx = xx - start; 576b8f8c88eSHong Zhang vscale_array = vscale_array - start; 577b8f8c88eSHong Zhang col_start = start; col_end = N + start; 578b8f8c88eSHong Zhang } 579b8f8c88eSHong Zhang for (col=col_start; col<col_end; col++){ 580b8f8c88eSHong Zhang /* Loop over each local column, vscale[col] = 1./(epsilon*dx[col]) */ 581efb30889SBarry Smith if (coloring->htype[0] == 'w') { 582efb30889SBarry Smith dx = 1.0 + unorm; 583efb30889SBarry Smith } else { 5849782cf98SBarry Smith dx = xx[col]; 585efb30889SBarry Smith } 586d4a378daSJed Brown if (dx == (PetscScalar)0.0) dx = 1.0; 5879782cf98SBarry Smith #if !defined(PETSC_USE_COMPLEX) 5889782cf98SBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 5899782cf98SBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 5909782cf98SBarry Smith #else 5919782cf98SBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 5929782cf98SBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 5939782cf98SBarry Smith #endif 5949782cf98SBarry Smith dx *= epsilon; 595d4a378daSJed Brown vscale_array[col] = (PetscScalar)1.0/dx; 5969782cf98SBarry Smith } 5978ee2e534SBarry Smith if (ctype == IS_COLORING_GLOBAL) vscale_array = vscale_array + start; 598efb30889SBarry Smith ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 5998ee2e534SBarry Smith if (ctype == IS_COLORING_GLOBAL){ 60030b34957SBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60130b34957SBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 602b8f8c88eSHong Zhang } 6039782cf98SBarry Smith 604b8f8c88eSHong Zhang if (coloring->vscaleforrow) { 605b8f8c88eSHong Zhang vscaleforrow = coloring->vscaleforrow; 60617186662SBarry Smith } else SETERRQ(((PetscObject)J)->comm,PETSC_ERR_ARG_NULL,"Null Object: coloring->vscaleforrow"); 607b0a32e0cSBarry Smith 6089782cf98SBarry Smith /* 60943a90d84SBarry Smith Loop over each color 61043a90d84SBarry Smith */ 611b8f8c88eSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 61243a90d84SBarry Smith for (k=0; k<coloring->ncolors; k++) { 61349b058dcSBarry Smith coloring->currentcolor = k; 614b8f8c88eSHong Zhang ierr = VecCopy(x1_tmp,w3);CHKERRQ(ierr); 615b8f8c88eSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr); 6168ee2e534SBarry Smith if (ctype == IS_COLORING_GLOBAL) w3_array = w3_array - start; 61743a90d84SBarry Smith /* 618b8f8c88eSHong Zhang Loop over each column associated with color 619b8f8c88eSHong Zhang adding the perturbation to the vector w3. 62043a90d84SBarry Smith */ 62143a90d84SBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 622b8f8c88eSHong Zhang col = coloring->columns[k][l]; /* local column of the matrix we are probing for */ 623efb30889SBarry Smith if (coloring->htype[0] == 'w') { 624efb30889SBarry Smith dx = 1.0 + unorm; 625efb30889SBarry Smith } else { 62642460c72SBarry Smith dx = xx[col]; 627efb30889SBarry Smith } 628d4a378daSJed Brown if (dx == (PetscScalar)0.0) dx = 1.0; 629aa482453SBarry Smith #if !defined(PETSC_USE_COMPLEX) 630ae09f205SBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 631ae09f205SBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 63243a90d84SBarry Smith #else 633329f5518SBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 634329f5518SBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 63543a90d84SBarry Smith #endif 63643a90d84SBarry Smith dx *= epsilon; 637e32f2f54SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 63842460c72SBarry Smith w3_array[col] += dx; 63943a90d84SBarry Smith } 64098d79826SSatish Balay if (ctype == IS_COLORING_GLOBAL) w3_array = w3_array + start; 641b8f8c88eSHong Zhang ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 6423b28642cSBarry Smith 64343a90d84SBarry Smith /* 644b8f8c88eSHong Zhang Evaluate function at w3 = x1 + dx (here dx is a vector of perturbations) 645b8f8c88eSHong Zhang w2 = F(x1 + dx) - F(x1) 64643a90d84SBarry Smith */ 64766f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 64843a90d84SBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 64966f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 650efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 6519782cf98SBarry Smith 65243a90d84SBarry Smith /* 653e0907662SLois Curfman McInnes Loop over rows of vector, putting results into Jacobian matrix 65443a90d84SBarry Smith */ 6553b28642cSBarry Smith ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 65643a90d84SBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 657b8f8c88eSHong Zhang row = coloring->rows[k][l]; /* local row index */ 658b8f8c88eSHong Zhang col = coloring->columnsforrow[k][l]; /* global column index */ 6595904e1b1SBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 66043a90d84SBarry Smith srow = row + start; 66143a90d84SBarry Smith ierr = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 66243a90d84SBarry Smith } 6633b28642cSBarry Smith ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 664aeb7e98aSMatthew Knepley } /* endof for each color */ 6658ee2e534SBarry Smith if (ctype == IS_COLORING_GLOBAL) xx = xx + start; 66630b34957SBarry Smith ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 667b8f8c88eSHong Zhang ierr = VecRestoreArray(x1_tmp,&xx);CHKERRQ(ierr); 668b8f8c88eSHong Zhang 669b8f8c88eSHong Zhang coloring->currentcolor = -1; 67043a90d84SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 67143a90d84SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 672d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr); 673a2e34c3dSBarry Smith 674*e350db43SBarry Smith ierr = MatFDColoringViewFromOptions(coloring,"-mat_fd_coloring_view");CHKERRQ(ierr); 6753a40ed3dSBarry Smith PetscFunctionReturn(0); 67643a90d84SBarry Smith } 677