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 282e350db43SBarry Smith . -mat_fd_coloring_view ::ascii_info - Activates viewing info 283e350db43SBarry 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__ 317e350db43SBarry Smith #define __FUNCT__ "MatFDColoringViewFromOptions" 318e350db43SBarry Smith PetscErrorCode MatFDColoringViewFromOptions(MatFDColoring fd,const char optionname[]) 319005c665bSBarry Smith { 320dfbe8321SBarry Smith PetscErrorCode ierr; 321e350db43SBarry Smith PetscBool flg; 3223050cee2SBarry Smith PetscViewer viewer; 323*cffb1e40SBarry Smith PetscViewerFormat format; 324005c665bSBarry Smith 3253a40ed3dSBarry Smith PetscFunctionBegin; 326*cffb1e40SBarry Smith ierr = PetscOptionsGetViewer(((PetscObject)fd)->comm,((PetscObject)fd)->prefix,optionname,&viewer,&format,&flg);CHKERRQ(ierr); 327005c665bSBarry Smith if (flg) { 328*cffb1e40SBarry Smith ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 3293050cee2SBarry Smith ierr = MatFDColoringView(fd,viewer);CHKERRQ(ierr); 330*cffb1e40SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 331*cffb1e40SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 332005c665bSBarry Smith } 3333a40ed3dSBarry Smith PetscFunctionReturn(0); 334bbf0e169SBarry Smith } 335bbf0e169SBarry Smith 3364a2ae208SSatish Balay #undef __FUNCT__ 3374a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate" 33805869f15SSatish Balay /*@ 339639f9d9dSBarry Smith MatFDColoringCreate - Creates a matrix coloring context for finite difference 340639f9d9dSBarry Smith computation of Jacobians. 341bbf0e169SBarry Smith 342ef5ee4d1SLois Curfman McInnes Collective on Mat 343ef5ee4d1SLois Curfman McInnes 344639f9d9dSBarry Smith Input Parameters: 345ef5ee4d1SLois Curfman McInnes + mat - the matrix containing the nonzero structure of the Jacobian 346e727c939SJed Brown - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring() 347bbf0e169SBarry Smith 348bbf0e169SBarry Smith Output Parameter: 349639f9d9dSBarry Smith . color - the new coloring context 350bbf0e169SBarry Smith 35115091d37SBarry Smith Level: intermediate 35215091d37SBarry Smith 3536831982aSBarry Smith .seealso: MatFDColoringDestroy(),SNESDefaultComputeJacobianColor(), ISColoringCreate(), 354d1c39f55SBarry Smith MatFDColoringSetFunction(), MatFDColoringSetFromOptions(), MatFDColoringApply(), 355e727c939SJed Brown MatFDColoringView(), MatFDColoringSetParameters(), MatGetColoring(), DMCreateColoring() 356bbf0e169SBarry Smith @*/ 3577087cfbeSBarry Smith PetscErrorCode MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color) 358bbf0e169SBarry Smith { 359639f9d9dSBarry Smith MatFDColoring c; 360639f9d9dSBarry Smith MPI_Comm comm; 361dfbe8321SBarry Smith PetscErrorCode ierr; 36238baddfdSBarry Smith PetscInt M,N; 363639f9d9dSBarry Smith 3643a40ed3dSBarry Smith PetscFunctionBegin; 365d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(MAT_FDColoringCreate,mat,0,0,0);CHKERRQ(ierr); 366639f9d9dSBarry Smith ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 36717186662SBarry Smith if (M != N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Only for square matrices"); 368f881d145SBarry Smith ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3693194b578SJed 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); 370639f9d9dSBarry Smith 371b8f8c88eSHong Zhang c->ctype = iscoloring->ctype; 372b8f8c88eSHong Zhang 373f830108cSBarry Smith if (mat->ops->fdcoloringcreate) { 374f830108cSBarry Smith ierr = (*mat->ops->fdcoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 375577b14d0SJed Brown } else SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 376639f9d9dSBarry Smith 377b8f8c88eSHong Zhang ierr = MatGetVecs(mat,PETSC_NULL,&c->w1);CHKERRQ(ierr); 378b8f8c88eSHong Zhang ierr = PetscLogObjectParent(c,c->w1);CHKERRQ(ierr); 379b8f8c88eSHong Zhang ierr = VecDuplicate(c->w1,&c->w2);CHKERRQ(ierr); 380b8f8c88eSHong Zhang ierr = PetscLogObjectParent(c,c->w2);CHKERRQ(ierr); 381b8f8c88eSHong Zhang 38277d8c4bbSBarry Smith c->error_rel = PETSC_SQRT_MACHINE_EPSILON; 38377d8c4bbSBarry Smith c->umin = 100.0*PETSC_SQRT_MACHINE_EPSILON; 38449b058dcSBarry Smith c->currentcolor = -1; 385efb30889SBarry Smith c->htype = "wp"; 3864e269d77SPeter Brune c->fset = PETSC_FALSE; 387639f9d9dSBarry Smith 388639f9d9dSBarry Smith *color = c; 3894e269d77SPeter Brune ierr = PetscObjectCompose((PetscObject)mat,"SNESMatFDColoring",(PetscObject)c);CHKERRQ(ierr); 390d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(MAT_FDColoringCreate,mat,0,0,0);CHKERRQ(ierr); 3913a40ed3dSBarry Smith PetscFunctionReturn(0); 392bbf0e169SBarry Smith } 393bbf0e169SBarry Smith 3944a2ae208SSatish Balay #undef __FUNCT__ 3954a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringDestroy" 39605869f15SSatish Balay /*@ 397639f9d9dSBarry Smith MatFDColoringDestroy - Destroys a matrix coloring context that was created 398639f9d9dSBarry Smith via MatFDColoringCreate(). 399bbf0e169SBarry Smith 400ef5ee4d1SLois Curfman McInnes Collective on MatFDColoring 401ef5ee4d1SLois Curfman McInnes 402b4fc646aSLois Curfman McInnes Input Parameter: 403639f9d9dSBarry Smith . c - coloring context 404bbf0e169SBarry Smith 40515091d37SBarry Smith Level: intermediate 40615091d37SBarry Smith 407639f9d9dSBarry Smith .seealso: MatFDColoringCreate() 408bbf0e169SBarry Smith @*/ 4096bf464f9SBarry Smith PetscErrorCode MatFDColoringDestroy(MatFDColoring *c) 410bbf0e169SBarry Smith { 4116849ba73SBarry Smith PetscErrorCode ierr; 41238baddfdSBarry Smith PetscInt i; 413bbf0e169SBarry Smith 4143a40ed3dSBarry Smith PetscFunctionBegin; 4156bf464f9SBarry Smith if (!*c) PetscFunctionReturn(0); 4166bf464f9SBarry Smith if (--((PetscObject)(*c))->refct > 0) {*c = 0; PetscFunctionReturn(0);} 417d4bb536fSBarry Smith 4186bf464f9SBarry Smith for (i=0; i<(*c)->ncolors; i++) { 4196bf464f9SBarry Smith ierr = PetscFree((*c)->columns[i]);CHKERRQ(ierr); 4206bf464f9SBarry Smith ierr = PetscFree((*c)->rows[i]);CHKERRQ(ierr); 4216bf464f9SBarry Smith ierr = PetscFree((*c)->columnsforrow[i]);CHKERRQ(ierr); 4226bf464f9SBarry Smith if ((*c)->vscaleforrow) {ierr = PetscFree((*c)->vscaleforrow[i]);CHKERRQ(ierr);} 423bbf0e169SBarry Smith } 4246bf464f9SBarry Smith ierr = PetscFree((*c)->ncolumns);CHKERRQ(ierr); 4256bf464f9SBarry Smith ierr = PetscFree((*c)->columns);CHKERRQ(ierr); 4266bf464f9SBarry Smith ierr = PetscFree((*c)->nrows);CHKERRQ(ierr); 4276bf464f9SBarry Smith ierr = PetscFree((*c)->rows);CHKERRQ(ierr); 4286bf464f9SBarry Smith ierr = PetscFree((*c)->columnsforrow);CHKERRQ(ierr); 4296bf464f9SBarry Smith ierr = PetscFree((*c)->vscaleforrow);CHKERRQ(ierr); 4306bf464f9SBarry Smith ierr = VecDestroy(&(*c)->vscale);CHKERRQ(ierr); 4316bf464f9SBarry Smith ierr = VecDestroy(&(*c)->w1);CHKERRQ(ierr); 4326bf464f9SBarry Smith ierr = VecDestroy(&(*c)->w2);CHKERRQ(ierr); 4336bf464f9SBarry Smith ierr = VecDestroy(&(*c)->w3);CHKERRQ(ierr); 434d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 4353a40ed3dSBarry Smith PetscFunctionReturn(0); 436bbf0e169SBarry Smith } 43743a90d84SBarry Smith 4384a2ae208SSatish Balay #undef __FUNCT__ 43949b058dcSBarry Smith #define __FUNCT__ "MatFDColoringGetPerturbedColumns" 44049b058dcSBarry Smith /*@C 44149b058dcSBarry Smith MatFDColoringGetPerturbedColumns - Returns the indices of the columns that 44249b058dcSBarry Smith that are currently being perturbed. 44349b058dcSBarry Smith 44449b058dcSBarry Smith Not Collective 44549b058dcSBarry Smith 44649b058dcSBarry Smith Input Parameters: 44749b058dcSBarry Smith . coloring - coloring context created with MatFDColoringCreate() 44849b058dcSBarry Smith 44949b058dcSBarry Smith Output Parameters: 45049b058dcSBarry Smith + n - the number of local columns being perturbed 45149b058dcSBarry Smith - cols - the column indices, in global numbering 45249b058dcSBarry Smith 45349b058dcSBarry Smith Level: intermediate 45449b058dcSBarry Smith 45549b058dcSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView(), MatFDColoringApply() 45649b058dcSBarry Smith 45749b058dcSBarry Smith .keywords: coloring, Jacobian, finite differences 45849b058dcSBarry Smith @*/ 4597087cfbeSBarry Smith PetscErrorCode MatFDColoringGetPerturbedColumns(MatFDColoring coloring,PetscInt *n,PetscInt *cols[]) 46049b058dcSBarry Smith { 46149b058dcSBarry Smith PetscFunctionBegin; 46249b058dcSBarry Smith if (coloring->currentcolor >= 0) { 46349b058dcSBarry Smith *n = coloring->ncolumns[coloring->currentcolor]; 46449b058dcSBarry Smith *cols = coloring->columns[coloring->currentcolor]; 46549b058dcSBarry Smith } else { 46649b058dcSBarry Smith *n = 0; 46749b058dcSBarry Smith } 46849b058dcSBarry Smith PetscFunctionReturn(0); 46949b058dcSBarry Smith } 47049b058dcSBarry Smith 47149b058dcSBarry Smith #undef __FUNCT__ 4724a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringApply" 47343a90d84SBarry Smith /*@ 474e0907662SLois Curfman McInnes MatFDColoringApply - Given a matrix for which a MatFDColoring context 475e0907662SLois Curfman McInnes has been created, computes the Jacobian for a function via finite differences. 47643a90d84SBarry Smith 477fee21e36SBarry Smith Collective on MatFDColoring 478fee21e36SBarry Smith 479ef5ee4d1SLois Curfman McInnes Input Parameters: 480ef5ee4d1SLois Curfman McInnes + mat - location to store Jacobian 481ef5ee4d1SLois Curfman McInnes . coloring - coloring context created with MatFDColoringCreate() 482ef5ee4d1SLois Curfman McInnes . x1 - location at which Jacobian is to be computed 4837850c7c0SBarry Smith - sctx - context required by function, if this is being used with the SNES solver then it is SNES object, otherwise it is null 484ef5ee4d1SLois Curfman McInnes 4858bba8e72SBarry Smith Options Database Keys: 486ebd3b9afSBarry Smith + -mat_fd_type - "wp" or "ds" (see MATMFFD_WP or MATMFFD_DS) 487b9722508SLois Curfman McInnes . -mat_fd_coloring_view - Activates basic viewing or coloring 488e350db43SBarry Smith . -mat_fd_coloring_view draw - Activates drawing of coloring 489e350db43SBarry Smith - -mat_fd_coloring_view ::ascii_info - Activates viewing of coloring info 4908bba8e72SBarry Smith 49115091d37SBarry Smith Level: intermediate 49298d79826SSatish Balay 4937850c7c0SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView(), MatFDColoringSetFunction() 49443a90d84SBarry Smith 49543a90d84SBarry Smith .keywords: coloring, Jacobian, finite differences 49643a90d84SBarry Smith @*/ 4977087cfbeSBarry Smith PetscErrorCode MatFDColoringApply(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 49843a90d84SBarry Smith { 4993acb8795SBarry Smith PetscErrorCode ierr; 5003acb8795SBarry Smith 5013acb8795SBarry Smith PetscFunctionBegin; 5020700a824SBarry Smith PetscValidHeaderSpecific(J,MAT_CLASSID,1); 5030700a824SBarry Smith PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_CLASSID,2); 5040700a824SBarry Smith PetscValidHeaderSpecific(x1,VEC_CLASSID,3); 50517186662SBarry Smith if (!coloring->f) SETERRQ(((PetscObject)J)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetFunction()"); 506e32f2f54SBarry Smith if (!J->ops->fdcoloringapply) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)J)->type_name); 5073acb8795SBarry Smith ierr = (*J->ops->fdcoloringapply)(J,coloring,x1,flag,sctx);CHKERRQ(ierr); 5083acb8795SBarry Smith PetscFunctionReturn(0); 5093acb8795SBarry Smith } 5103acb8795SBarry Smith 5113acb8795SBarry Smith #undef __FUNCT__ 5123acb8795SBarry Smith #define __FUNCT__ "MatFDColoringApply_AIJ" 5137087cfbeSBarry Smith PetscErrorCode MatFDColoringApply_AIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 5143acb8795SBarry Smith { 5156849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 5166849ba73SBarry Smith PetscErrorCode ierr; 5174e269d77SPeter Brune PetscInt k,start,end,l,row,col,srow,**vscaleforrow; 518efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 519ea709b57SSatish Balay PetscScalar *vscale_array; 520efb30889SBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin,unorm; 521b8f8c88eSHong Zhang Vec w1=coloring->w1,w2=coloring->w2,w3; 522005c665bSBarry Smith void *fctx = coloring->fctx; 523ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 524705d48f7SSatish Balay PetscInt ctype=coloring->ctype,N,col_start=0,col_end=0; 525b8f8c88eSHong Zhang Vec x1_tmp; 526a2e34c3dSBarry Smith 5273a40ed3dSBarry Smith PetscFunctionBegin; 5280700a824SBarry Smith PetscValidHeaderSpecific(J,MAT_CLASSID,1); 5290700a824SBarry Smith PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_CLASSID,2); 5300700a824SBarry Smith PetscValidHeaderSpecific(x1,VEC_CLASSID,3); 53117186662SBarry Smith if (!f) SETERRQ(((PetscObject)J)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetFunction()"); 532e0907662SLois Curfman McInnes 533d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr); 5344c49b128SBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 535acfcf0e5SJed Brown ierr = PetscOptionsGetBool(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr); 536f1af5d2fSBarry Smith if (flg) { 537ae15b995SBarry Smith ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 538e0907662SLois Curfman McInnes } else { 539ace3abfcSBarry Smith PetscBool assembled; 5400b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 5410b9b6f31SBarry Smith if (assembled) { 54243a90d84SBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 543e0907662SLois Curfman McInnes } 5440b9b6f31SBarry Smith } 54543a90d84SBarry Smith 546b8f8c88eSHong Zhang x1_tmp = x1; 547dac7f5fdSBarry Smith if (!coloring->vscale){ 548b8f8c88eSHong Zhang ierr = VecDuplicate(x1_tmp,&coloring->vscale);CHKERRQ(ierr); 549b8f8c88eSHong Zhang } 550be2fbe1fSBarry Smith 551b8f8c88eSHong Zhang if (coloring->htype[0] == 'w') { /* tacky test; need to make systematic if we add other approaches to computing h*/ 552b8f8c88eSHong Zhang ierr = VecNorm(x1_tmp,NORM_2,&unorm);CHKERRQ(ierr); 553b8f8c88eSHong Zhang } 554b8f8c88eSHong Zhang ierr = VecGetOwnershipRange(w1,&start,&end);CHKERRQ(ierr); /* OwnershipRange is used by ghosted x! */ 555b8f8c88eSHong Zhang 556b8f8c88eSHong Zhang /* Set w1 = F(x1) */ 5574e269d77SPeter Brune if (!coloring->fset) { 55866f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 559b8f8c88eSHong Zhang ierr = (*f)(sctx,x1_tmp,w1,fctx);CHKERRQ(ierr); 56066f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 5614e269d77SPeter Brune } else { 5624e269d77SPeter Brune coloring->fset = PETSC_FALSE; 563be2fbe1fSBarry Smith } 56443a90d84SBarry Smith 565b8f8c88eSHong Zhang if (!coloring->w3) { 566b8f8c88eSHong Zhang ierr = VecDuplicate(x1_tmp,&coloring->w3);CHKERRQ(ierr); 567b8f8c88eSHong Zhang ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 568efb30889SBarry Smith } 569b8f8c88eSHong Zhang w3 = coloring->w3; 570efb30889SBarry Smith 571b8f8c88eSHong Zhang /* Compute all the local scale factors, including ghost points */ 572b8f8c88eSHong Zhang ierr = VecGetLocalSize(x1_tmp,&N);CHKERRQ(ierr); 573b8f8c88eSHong Zhang ierr = VecGetArray(x1_tmp,&xx);CHKERRQ(ierr); 574b8f8c88eSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 575b8f8c88eSHong Zhang if (ctype == IS_COLORING_GHOSTED){ 576b8f8c88eSHong Zhang col_start = 0; col_end = N; 5778ee2e534SBarry Smith } else if (ctype == IS_COLORING_GLOBAL){ 578b8f8c88eSHong Zhang xx = xx - start; 579b8f8c88eSHong Zhang vscale_array = vscale_array - start; 580b8f8c88eSHong Zhang col_start = start; col_end = N + start; 581b8f8c88eSHong Zhang } 582b8f8c88eSHong Zhang for (col=col_start; col<col_end; col++){ 583b8f8c88eSHong Zhang /* Loop over each local column, vscale[col] = 1./(epsilon*dx[col]) */ 584efb30889SBarry Smith if (coloring->htype[0] == 'w') { 585efb30889SBarry Smith dx = 1.0 + unorm; 586efb30889SBarry Smith } else { 5879782cf98SBarry Smith dx = xx[col]; 588efb30889SBarry Smith } 589d4a378daSJed Brown if (dx == (PetscScalar)0.0) dx = 1.0; 5909782cf98SBarry Smith #if !defined(PETSC_USE_COMPLEX) 5919782cf98SBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 5929782cf98SBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 5939782cf98SBarry Smith #else 5949782cf98SBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 5959782cf98SBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 5969782cf98SBarry Smith #endif 5979782cf98SBarry Smith dx *= epsilon; 598d4a378daSJed Brown vscale_array[col] = (PetscScalar)1.0/dx; 5999782cf98SBarry Smith } 6008ee2e534SBarry Smith if (ctype == IS_COLORING_GLOBAL) vscale_array = vscale_array + start; 601efb30889SBarry Smith ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 6028ee2e534SBarry Smith if (ctype == IS_COLORING_GLOBAL){ 60330b34957SBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60430b34957SBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 605b8f8c88eSHong Zhang } 6069782cf98SBarry Smith 607b8f8c88eSHong Zhang if (coloring->vscaleforrow) { 608b8f8c88eSHong Zhang vscaleforrow = coloring->vscaleforrow; 60917186662SBarry Smith } else SETERRQ(((PetscObject)J)->comm,PETSC_ERR_ARG_NULL,"Null Object: coloring->vscaleforrow"); 610b0a32e0cSBarry Smith 6119782cf98SBarry Smith /* 61243a90d84SBarry Smith Loop over each color 61343a90d84SBarry Smith */ 614b8f8c88eSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 61543a90d84SBarry Smith for (k=0; k<coloring->ncolors; k++) { 61649b058dcSBarry Smith coloring->currentcolor = k; 617b8f8c88eSHong Zhang ierr = VecCopy(x1_tmp,w3);CHKERRQ(ierr); 618b8f8c88eSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr); 6198ee2e534SBarry Smith if (ctype == IS_COLORING_GLOBAL) w3_array = w3_array - start; 62043a90d84SBarry Smith /* 621b8f8c88eSHong Zhang Loop over each column associated with color 622b8f8c88eSHong Zhang adding the perturbation to the vector w3. 62343a90d84SBarry Smith */ 62443a90d84SBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 625b8f8c88eSHong Zhang col = coloring->columns[k][l]; /* local column of the matrix we are probing for */ 626efb30889SBarry Smith if (coloring->htype[0] == 'w') { 627efb30889SBarry Smith dx = 1.0 + unorm; 628efb30889SBarry Smith } else { 62942460c72SBarry Smith dx = xx[col]; 630efb30889SBarry Smith } 631d4a378daSJed Brown if (dx == (PetscScalar)0.0) dx = 1.0; 632aa482453SBarry Smith #if !defined(PETSC_USE_COMPLEX) 633ae09f205SBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 634ae09f205SBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 63543a90d84SBarry Smith #else 636329f5518SBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 637329f5518SBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 63843a90d84SBarry Smith #endif 63943a90d84SBarry Smith dx *= epsilon; 640e32f2f54SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 64142460c72SBarry Smith w3_array[col] += dx; 64243a90d84SBarry Smith } 64398d79826SSatish Balay if (ctype == IS_COLORING_GLOBAL) w3_array = w3_array + start; 644b8f8c88eSHong Zhang ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 6453b28642cSBarry Smith 64643a90d84SBarry Smith /* 647b8f8c88eSHong Zhang Evaluate function at w3 = x1 + dx (here dx is a vector of perturbations) 648b8f8c88eSHong Zhang w2 = F(x1 + dx) - F(x1) 64943a90d84SBarry Smith */ 65066f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 65143a90d84SBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 65266f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 653efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 6549782cf98SBarry Smith 65543a90d84SBarry Smith /* 656e0907662SLois Curfman McInnes Loop over rows of vector, putting results into Jacobian matrix 65743a90d84SBarry Smith */ 6583b28642cSBarry Smith ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 65943a90d84SBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 660b8f8c88eSHong Zhang row = coloring->rows[k][l]; /* local row index */ 661b8f8c88eSHong Zhang col = coloring->columnsforrow[k][l]; /* global column index */ 6625904e1b1SBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 66343a90d84SBarry Smith srow = row + start; 66443a90d84SBarry Smith ierr = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 66543a90d84SBarry Smith } 6663b28642cSBarry Smith ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 667aeb7e98aSMatthew Knepley } /* endof for each color */ 6688ee2e534SBarry Smith if (ctype == IS_COLORING_GLOBAL) xx = xx + start; 66930b34957SBarry Smith ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 670b8f8c88eSHong Zhang ierr = VecRestoreArray(x1_tmp,&xx);CHKERRQ(ierr); 671b8f8c88eSHong Zhang 672b8f8c88eSHong Zhang coloring->currentcolor = -1; 67343a90d84SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 67443a90d84SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 675d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr); 676a2e34c3dSBarry Smith 677e350db43SBarry Smith ierr = MatFDColoringViewFromOptions(coloring,"-mat_fd_coloring_view");CHKERRQ(ierr); 6783a40ed3dSBarry Smith PetscFunctionReturn(0); 67943a90d84SBarry Smith } 680