xref: /petsc/src/mat/matfd/fdmatrix.c (revision d1e9a80f72efc361583d2fc822de9783b227627d)
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;
146e111a19SKarl Rupp 
153a7fca6bSBarry Smith   PetscFunctionBegin;
164e269d77SPeter Brune   if (F) {
174e269d77SPeter Brune     ierr     = VecCopy(F,fd->w1);CHKERRQ(ierr);
184e269d77SPeter Brune     fd->fset = PETSC_TRUE;
194e269d77SPeter Brune   } else {
204e269d77SPeter Brune     fd->fset = PETSC_FALSE;
214e269d77SPeter Brune   }
223a7fca6bSBarry Smith   PetscFunctionReturn(0);
233a7fca6bSBarry Smith }
243a7fca6bSBarry Smith 
259804daf3SBarry Smith #include <petscdraw.h>
263a7fca6bSBarry Smith #undef __FUNCT__
274a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringView_Draw_Zoom"
286849ba73SBarry Smith static PetscErrorCode MatFDColoringView_Draw_Zoom(PetscDraw draw,void *Aa)
299194eea9SBarry Smith {
309194eea9SBarry Smith   MatFDColoring  fd = (MatFDColoring)Aa;
31dfbe8321SBarry Smith   PetscErrorCode ierr;
32b312708bSHong Zhang   PetscInt       i,j,nz,row;
339194eea9SBarry Smith   PetscReal      x,y;
34b312708bSHong Zhang   MatEntry       *Jentry=fd->matentry;
359194eea9SBarry Smith 
369194eea9SBarry Smith   PetscFunctionBegin;
379194eea9SBarry Smith   /* loop over colors  */
38b312708bSHong Zhang   nz = 0;
399194eea9SBarry Smith   for (i=0; i<fd->ncolors; i++) {
409194eea9SBarry Smith     for (j=0; j<fd->nrows[i]; j++) {
41b312708bSHong Zhang       row = Jentry[nz].row;
42b312708bSHong Zhang       y   = fd->M - row - fd->rstart;
43b312708bSHong Zhang       x   = (PetscReal)Jentry[nz++].col;
44b0a32e0cSBarry Smith       ierr = PetscDrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1);CHKERRQ(ierr);
459194eea9SBarry Smith     }
469194eea9SBarry Smith   }
479194eea9SBarry Smith   PetscFunctionReturn(0);
489194eea9SBarry Smith }
499194eea9SBarry Smith 
504a2ae208SSatish Balay #undef __FUNCT__
514a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringView_Draw"
526849ba73SBarry Smith static PetscErrorCode MatFDColoringView_Draw(MatFDColoring fd,PetscViewer viewer)
53005c665bSBarry Smith {
54dfbe8321SBarry Smith   PetscErrorCode ierr;
55ace3abfcSBarry Smith   PetscBool      isnull;
56b0a32e0cSBarry Smith   PetscDraw      draw;
5754d96fa3SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
58005c665bSBarry Smith 
593a40ed3dSBarry Smith   PetscFunctionBegin;
60b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
61b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
629194eea9SBarry Smith 
639194eea9SBarry Smith   ierr = PetscObjectCompose((PetscObject)fd,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
64005c665bSBarry Smith 
65005c665bSBarry Smith   xr   = fd->N; yr  = fd->M; h = yr/10.0; w = xr/10.0;
66005c665bSBarry Smith   xr  += w;     yr += h;    xl = -w;     yl = -h;
67b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
68b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatFDColoringView_Draw_Zoom,fd);CHKERRQ(ierr);
69f77a5242SKarl Rupp   ierr = PetscObjectCompose((PetscObject)fd,"Zoomviewer",NULL);CHKERRQ(ierr);
703a40ed3dSBarry Smith   PetscFunctionReturn(0);
71005c665bSBarry Smith }
72005c665bSBarry Smith 
734a2ae208SSatish Balay #undef __FUNCT__
744a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringView"
75bbf0e169SBarry Smith /*@C
76639f9d9dSBarry Smith    MatFDColoringView - Views a finite difference coloring context.
77bbf0e169SBarry Smith 
784c49b128SBarry Smith    Collective on MatFDColoring
79fee21e36SBarry Smith 
80ef5ee4d1SLois Curfman McInnes    Input  Parameters:
81ef5ee4d1SLois Curfman McInnes +  c - the coloring context
82ef5ee4d1SLois Curfman McInnes -  viewer - visualization context
83ef5ee4d1SLois Curfman McInnes 
8415091d37SBarry Smith    Level: intermediate
8515091d37SBarry Smith 
86b4fc646aSLois Curfman McInnes    Notes:
87b4fc646aSLois Curfman McInnes    The available visualization contexts include
88b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
89b0a32e0cSBarry Smith .     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
90ef5ee4d1SLois Curfman McInnes         output where only the first processor opens
91ef5ee4d1SLois Curfman McInnes         the file.  All other processors send their
92ef5ee4d1SLois Curfman McInnes         data to the first processor to print.
93b0a32e0cSBarry Smith -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
94bbf0e169SBarry Smith 
959194eea9SBarry Smith    Notes:
969194eea9SBarry Smith      Since PETSc uses only a small number of basic colors (currently 33), if the coloring
97b0a32e0cSBarry Smith    involves more than 33 then some seemingly identical colors are displayed making it look
989194eea9SBarry Smith    like an illegal coloring. This is just a graphical artifact.
999194eea9SBarry Smith 
100639f9d9dSBarry Smith .seealso: MatFDColoringCreate()
101005c665bSBarry Smith 
102b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, view
103bbf0e169SBarry Smith @*/
1047087cfbeSBarry Smith PetscErrorCode  MatFDColoringView(MatFDColoring c,PetscViewer viewer)
105bbf0e169SBarry Smith {
1066849ba73SBarry Smith   PetscErrorCode    ierr;
10738baddfdSBarry Smith   PetscInt          i,j;
108ace3abfcSBarry Smith   PetscBool         isdraw,iascii;
109f3ef73ceSBarry Smith   PetscViewerFormat format;
110bbf0e169SBarry Smith 
1113a40ed3dSBarry Smith   PetscFunctionBegin;
1120700a824SBarry Smith   PetscValidHeaderSpecific(c,MAT_FDCOLORING_CLASSID,1);
1133050cee2SBarry Smith   if (!viewer) {
114ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)c),&viewer);CHKERRQ(ierr);
1153050cee2SBarry Smith   }
1160700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
117c9780b6fSBarry Smith   PetscCheckSameComm(c,1,viewer,2);
118bbf0e169SBarry Smith 
119251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
120251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1210f5bd95cSBarry Smith   if (isdraw) {
122b4fc646aSLois Curfman McInnes     ierr = MatFDColoringView_Draw(c,viewer);CHKERRQ(ierr);
12332077d6dSBarry Smith   } else if (iascii) {
124dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)c,viewer);CHKERRQ(ierr);
12557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Error tolerance=%g\n",(double)c->error_rel);CHKERRQ(ierr);
12657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Umin=%g\n",(double)c->umin);CHKERRQ(ierr);
12777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Number of colors=%D\n",c->ncolors);CHKERRQ(ierr);
128ae09f205SBarry Smith 
129b0a32e0cSBarry Smith     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
130fb9695e5SSatish Balay     if (format != PETSC_VIEWER_ASCII_INFO) {
131b312708bSHong Zhang       PetscInt row,col,nz;
132b312708bSHong Zhang       nz = 0;
133b4fc646aSLois Curfman McInnes       for (i=0; i<c->ncolors; i++) {
13477431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Information for color %D\n",i);CHKERRQ(ierr);
13577431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    Number of columns %D\n",c->ncolumns[i]);CHKERRQ(ierr);
136b4fc646aSLois Curfman McInnes         for (j=0; j<c->ncolumns[i]; j++) {
13777431f27SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"      %D\n",c->columns[i][j]);CHKERRQ(ierr);
138639f9d9dSBarry Smith         }
13977431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    Number of rows %D\n",c->nrows[i]);CHKERRQ(ierr);
140b4fc646aSLois Curfman McInnes         for (j=0; j<c->nrows[i]; j++) {
141b312708bSHong Zhang           row  = c->matentry[nz].row;
142b312708bSHong Zhang           col  = c->matentry[nz++].col;
143b312708bSHong Zhang           ierr = PetscViewerASCIIPrintf(viewer,"      %D %D \n",row,col);CHKERRQ(ierr);
144b4fc646aSLois Curfman McInnes         }
145bbf0e169SBarry Smith       }
146bbf0e169SBarry Smith     }
147b0a32e0cSBarry Smith     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
148bbf0e169SBarry Smith   }
1493a40ed3dSBarry Smith   PetscFunctionReturn(0);
150639f9d9dSBarry Smith }
151639f9d9dSBarry Smith 
1524a2ae208SSatish Balay #undef __FUNCT__
1534a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringSetParameters"
154639f9d9dSBarry Smith /*@
155b4fc646aSLois Curfman McInnes    MatFDColoringSetParameters - Sets the parameters for the sparse approximation of
156b4fc646aSLois Curfman McInnes    a Jacobian matrix using finite differences.
157639f9d9dSBarry Smith 
1583f9fe445SBarry Smith    Logically Collective on MatFDColoring
159ef5ee4d1SLois Curfman McInnes 
160ef5ee4d1SLois Curfman McInnes    The Jacobian is estimated with the differencing approximation
161ef5ee4d1SLois Curfman McInnes .vb
16265f2ba5bSLois Curfman McInnes        F'(u)_{:,i} = [F(u+h*dx_{i}) - F(u)]/h where
163f23b5b22SLois Curfman McInnes        h = error_rel*u[i]                 if  abs(u[i]) > umin
164f23b5b22SLois Curfman McInnes          = +/- error_rel*umin             otherwise, with +/- determined by the sign of u[i]
165ef5ee4d1SLois Curfman McInnes        dx_{i} = (0, ... 1, .... 0)
166ef5ee4d1SLois Curfman McInnes .ve
167639f9d9dSBarry Smith 
168639f9d9dSBarry Smith    Input Parameters:
169ef5ee4d1SLois Curfman McInnes +  coloring - the coloring context
170639f9d9dSBarry Smith .  error_rel - relative error
171f23b5b22SLois Curfman McInnes -  umin - minimum allowable u-value magnitude
172fee21e36SBarry Smith 
17315091d37SBarry Smith    Level: advanced
17415091d37SBarry Smith 
175b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, parameters
176b4fc646aSLois Curfman McInnes 
17795b89fc3SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringSetFromOptions()
17895b89fc3SBarry Smith 
179639f9d9dSBarry Smith @*/
1807087cfbeSBarry Smith PetscErrorCode MatFDColoringSetParameters(MatFDColoring matfd,PetscReal error,PetscReal umin)
181639f9d9dSBarry Smith {
1823a40ed3dSBarry Smith   PetscFunctionBegin;
1830700a824SBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1);
184c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(matfd,error,2);
185c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(matfd,umin,3);
186639f9d9dSBarry Smith   if (error != PETSC_DEFAULT) matfd->error_rel = error;
187639f9d9dSBarry Smith   if (umin != PETSC_DEFAULT)  matfd->umin      = umin;
1883a40ed3dSBarry Smith   PetscFunctionReturn(0);
189639f9d9dSBarry Smith }
190639f9d9dSBarry Smith 
191f86b9fbaSHong Zhang #undef __FUNCT__
192f86b9fbaSHong Zhang #define __FUNCT__ "MatFDColoringSetBlockSize"
193f86b9fbaSHong Zhang /*@
194c8a9c622SHong Zhang    MatFDColoringSetBlockSize - Sets block size for efficient inserting entries of Jacobian matrix.
195005c665bSBarry Smith 
196f86b9fbaSHong Zhang    Logically Collective on MatFDColoring
197f86b9fbaSHong Zhang 
198f86b9fbaSHong Zhang    Input Parameters:
199f86b9fbaSHong Zhang +  coloring - the coloring context
200f86b9fbaSHong Zhang .  brows - number of rows in the block
201f86b9fbaSHong Zhang -  bcols - number of columns in the block
202f86b9fbaSHong Zhang 
203f86b9fbaSHong Zhang    Level: intermediate
204f86b9fbaSHong Zhang 
205f86b9fbaSHong Zhang .keywords: Mat, coloring
206f86b9fbaSHong Zhang 
207f86b9fbaSHong Zhang .seealso: MatFDColoringCreate(), MatFDColoringSetFromOptions()
208f86b9fbaSHong Zhang 
209f86b9fbaSHong Zhang @*/
210f86b9fbaSHong Zhang PetscErrorCode MatFDColoringSetBlockSize(MatFDColoring matfd,PetscInt brows,PetscInt bcols)
211f86b9fbaSHong Zhang {
212f86b9fbaSHong Zhang   PetscFunctionBegin;
213f86b9fbaSHong Zhang   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1);
214f86b9fbaSHong Zhang   PetscValidLogicalCollectiveInt(matfd,brows,2);
215f86b9fbaSHong Zhang   PetscValidLogicalCollectiveInt(matfd,bcols,3);
216f86b9fbaSHong Zhang   if (brows != PETSC_DEFAULT) matfd->brows = brows;
217f86b9fbaSHong Zhang   if (bcols != PETSC_DEFAULT) matfd->bcols = bcols;
218f86b9fbaSHong Zhang   PetscFunctionReturn(0);
219f86b9fbaSHong Zhang }
220f86b9fbaSHong Zhang 
221f86b9fbaSHong Zhang #undef __FUNCT__
222f86b9fbaSHong Zhang #define __FUNCT__ "MatFDColoringSetUp"
223f86b9fbaSHong Zhang /*@
224f86b9fbaSHong Zhang    MatFDColoringSetUp - Sets up the internal data structures of matrix coloring context for the later use.
225f86b9fbaSHong Zhang 
226f86b9fbaSHong Zhang    Collective on Mat
227f86b9fbaSHong Zhang 
228f86b9fbaSHong Zhang    Input Parameters:
229f86b9fbaSHong Zhang +  mat - the matrix containing the nonzero structure of the Jacobian
230f86b9fbaSHong Zhang .  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
231f86b9fbaSHong Zhang -  color - the matrix coloring context
232f86b9fbaSHong Zhang 
233f86b9fbaSHong Zhang    Level: beginner
234f86b9fbaSHong Zhang 
235f86b9fbaSHong Zhang .keywords: MatFDColoring, setup
236f86b9fbaSHong Zhang 
237f86b9fbaSHong Zhang .seealso: MatFDColoringCreate(), MatFDColoringDestroy()
238f86b9fbaSHong Zhang @*/
239f86b9fbaSHong Zhang PetscErrorCode MatFDColoringSetUp(Mat mat,ISColoring iscoloring,MatFDColoring color)
240f86b9fbaSHong Zhang {
241f86b9fbaSHong Zhang   PetscErrorCode ierr;
242f86b9fbaSHong Zhang 
243f86b9fbaSHong Zhang   PetscFunctionBegin;
244c8a9c622SHong Zhang   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
245c8a9c622SHong Zhang   PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,3);
246c8a9c622SHong Zhang   if (color->setupcalled) PetscFunctionReturn(0);
247c8a9c622SHong Zhang 
2480df34763SHong Zhang   ierr = PetscLogEventBegin(MAT_FDColoringSetUp,mat,0,0,0);CHKERRQ(ierr);
249f86b9fbaSHong Zhang   if (mat->ops->fdcoloringsetup) {
250f86b9fbaSHong Zhang     ierr = (*mat->ops->fdcoloringsetup)(mat,iscoloring,color);CHKERRQ(ierr);
251f86b9fbaSHong Zhang   } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
252c8a9c622SHong Zhang 
253c8a9c622SHong Zhang   color->setupcalled = PETSC_TRUE;
2540df34763SHong Zhang    ierr   = PetscLogEventEnd(MAT_FDColoringSetUp,mat,0,0,0);CHKERRQ(ierr);
255f86b9fbaSHong Zhang   PetscFunctionReturn(0);
256f86b9fbaSHong Zhang }
257ff0cfa39SBarry Smith 
2584a2ae208SSatish Balay #undef __FUNCT__
2594a9d489dSBarry Smith #define __FUNCT__ "MatFDColoringGetFunction"
2604a9d489dSBarry Smith /*@C
2614a9d489dSBarry Smith    MatFDColoringGetFunction - Gets the function to use for computing the Jacobian.
2624a9d489dSBarry Smith 
2633f9fe445SBarry Smith    Not Collective
2644a9d489dSBarry Smith 
2654a9d489dSBarry Smith    Input Parameters:
2664a9d489dSBarry Smith .  coloring - the coloring context
2674a9d489dSBarry Smith 
2684a9d489dSBarry Smith    Output Parameters:
2694a9d489dSBarry Smith +  f - the function
2704a9d489dSBarry Smith -  fctx - the optional user-defined function context
2714a9d489dSBarry Smith 
2724a9d489dSBarry Smith    Level: intermediate
2734a9d489dSBarry Smith 
2744a9d489dSBarry Smith .keywords: Mat, Jacobian, finite differences, set, function
27595b89fc3SBarry Smith 
27695b89fc3SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringSetFunction(), MatFDColoringSetFromOptions()
27795b89fc3SBarry Smith 
2784a9d489dSBarry Smith @*/
2797087cfbeSBarry Smith PetscErrorCode  MatFDColoringGetFunction(MatFDColoring matfd,PetscErrorCode (**f)(void),void **fctx)
2804a9d489dSBarry Smith {
2814a9d489dSBarry Smith   PetscFunctionBegin;
2820700a824SBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1);
2834a9d489dSBarry Smith   if (f) *f = matfd->f;
2844a9d489dSBarry Smith   if (fctx) *fctx = matfd->fctx;
2854a9d489dSBarry Smith   PetscFunctionReturn(0);
2864a9d489dSBarry Smith }
2874a9d489dSBarry Smith 
2884a9d489dSBarry Smith #undef __FUNCT__
2894a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringSetFunction"
290d64ed03dSBarry Smith /*@C
291005c665bSBarry Smith    MatFDColoringSetFunction - Sets the function to use for computing the Jacobian.
292005c665bSBarry Smith 
2933f9fe445SBarry Smith    Logically Collective on MatFDColoring
294fee21e36SBarry Smith 
295ef5ee4d1SLois Curfman McInnes    Input Parameters:
296ef5ee4d1SLois Curfman McInnes +  coloring - the coloring context
297ef5ee4d1SLois Curfman McInnes .  f - the function
298ef5ee4d1SLois Curfman McInnes -  fctx - the optional user-defined function context
299ef5ee4d1SLois Curfman McInnes 
3007850c7c0SBarry Smith    Calling sequence of (*f) function:
3017850c7c0SBarry Smith     For SNES:    PetscErrorCode (*f)(SNES,Vec,Vec,void*)
302ab637aeaSJed Brown     If not using SNES: PetscErrorCode (*f)(void *dummy,Vec,Vec,void*) and dummy is ignored
30315091d37SBarry Smith 
3047850c7c0SBarry Smith    Level: advanced
3057850c7c0SBarry Smith 
306ab637aeaSJed Brown    Notes: This function is usually used automatically by SNES (when one uses SNESSetJacobian() with the argument
3078d359177SBarry Smith      SNESComputeJacobianDefaultColor()) and only needs to be used by someone computing a matrix via coloring directly by
308ab637aeaSJed Brown      calling MatFDColoringApply()
3097850c7c0SBarry Smith 
3107850c7c0SBarry Smith    Fortran Notes:
3117850c7c0SBarry Smith     In Fortran you must call MatFDColoringSetFunction() for a coloring object to
312ab637aeaSJed Brown   be used without SNES or within the SNES solvers.
313f881d145SBarry Smith 
314b4fc646aSLois Curfman McInnes .keywords: Mat, Jacobian, finite differences, set, function
31595b89fc3SBarry Smith 
31695b89fc3SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringGetFunction(), MatFDColoringSetFromOptions()
31795b89fc3SBarry Smith 
318005c665bSBarry Smith @*/
3197087cfbeSBarry Smith PetscErrorCode  MatFDColoringSetFunction(MatFDColoring matfd,PetscErrorCode (*f)(void),void *fctx)
320005c665bSBarry Smith {
3213a40ed3dSBarry Smith   PetscFunctionBegin;
3220700a824SBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1);
323005c665bSBarry Smith   matfd->f    = f;
324005c665bSBarry Smith   matfd->fctx = fctx;
3253a40ed3dSBarry Smith   PetscFunctionReturn(0);
326005c665bSBarry Smith }
327005c665bSBarry Smith 
3284a2ae208SSatish Balay #undef __FUNCT__
3294a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringSetFromOptions"
330639f9d9dSBarry Smith /*@
331b4fc646aSLois Curfman McInnes    MatFDColoringSetFromOptions - Sets coloring finite difference parameters from
332639f9d9dSBarry Smith    the options database.
333639f9d9dSBarry Smith 
334fee21e36SBarry Smith    Collective on MatFDColoring
335fee21e36SBarry Smith 
33665f2ba5bSLois Curfman McInnes    The Jacobian, F'(u), is estimated with the differencing approximation
337ef5ee4d1SLois Curfman McInnes .vb
33865f2ba5bSLois Curfman McInnes        F'(u)_{:,i} = [F(u+h*dx_{i}) - F(u)]/h where
339f23b5b22SLois Curfman McInnes        h = error_rel*u[i]                 if  abs(u[i]) > umin
340f23b5b22SLois Curfman McInnes          = +/- error_rel*umin             otherwise, with +/- determined by the sign of u[i]
341ef5ee4d1SLois Curfman McInnes        dx_{i} = (0, ... 1, .... 0)
342ef5ee4d1SLois Curfman McInnes .ve
343ef5ee4d1SLois Curfman McInnes 
344ef5ee4d1SLois Curfman McInnes    Input Parameter:
345ef5ee4d1SLois Curfman McInnes .  coloring - the coloring context
346ef5ee4d1SLois Curfman McInnes 
347b4fc646aSLois Curfman McInnes    Options Database Keys:
348d15ffeeaSSatish Balay +  -mat_fd_coloring_err <err> - Sets <err> (square root
349ef5ee4d1SLois Curfman McInnes            of relative error in the function)
350f23b5b22SLois Curfman McInnes .  -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude
3513ec795f1SBarry Smith .  -mat_fd_type - "wp" or "ds" (see MATMFFD_WP or MATMFFD_DS)
352ef5ee4d1SLois Curfman McInnes .  -mat_fd_coloring_view - Activates basic viewing
353e350db43SBarry Smith .  -mat_fd_coloring_view ::ascii_info - Activates viewing info
354e350db43SBarry Smith -  -mat_fd_coloring_view draw - Activates drawing
355639f9d9dSBarry Smith 
35615091d37SBarry Smith     Level: intermediate
35715091d37SBarry Smith 
358b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, parameters
359d1c39f55SBarry Smith 
360d1c39f55SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringView(), MatFDColoringSetParameters()
361d1c39f55SBarry Smith 
362639f9d9dSBarry Smith @*/
3637087cfbeSBarry Smith PetscErrorCode  MatFDColoringSetFromOptions(MatFDColoring matfd)
364639f9d9dSBarry Smith {
365dfbe8321SBarry Smith   PetscErrorCode ierr;
366ace3abfcSBarry Smith   PetscBool      flg;
367efb30889SBarry Smith   char           value[3];
3683a40ed3dSBarry Smith 
3693a40ed3dSBarry Smith   PetscFunctionBegin;
3700700a824SBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_CLASSID,1);
371639f9d9dSBarry Smith 
3723194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)matfd);CHKERRQ(ierr);
37387828ca2SBarry Smith   ierr = PetscOptionsReal("-mat_fd_coloring_err","Square root of relative error in function","MatFDColoringSetParameters",matfd->error_rel,&matfd->error_rel,0);CHKERRQ(ierr);
37487828ca2SBarry Smith   ierr = PetscOptionsReal("-mat_fd_coloring_umin","Minimum allowable u magnitude","MatFDColoringSetParameters",matfd->umin,&matfd->umin,0);CHKERRQ(ierr);
3751bc75a8dSBarry Smith   ierr = PetscOptionsString("-mat_fd_type","Algorithm to compute h, wp or ds","MatFDColoringCreate",matfd->htype,value,3,&flg);CHKERRQ(ierr);
376efb30889SBarry Smith   if (flg) {
377efb30889SBarry Smith     if (value[0] == 'w' && value[1] == 'p') matfd->htype = "wp";
378efb30889SBarry Smith     else if (value[0] == 'd' && value[1] == 's') matfd->htype = "ds";
379e32f2f54SBarry Smith     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown finite differencing type %s",value);
380efb30889SBarry Smith   }
381f86b9fbaSHong Zhang   ierr = PetscOptionsInt("-mat_fd_coloring_brows","Number of block rows","MatFDColoringSetBlockSize",matfd->brows,&matfd->brows,NULL);CHKERRQ(ierr);
38293dfae19SHong Zhang   ierr = PetscOptionsInt("-mat_fd_coloring_bcols","Number of block columns","MatFDColoringSetBlockSize",matfd->bcols,&matfd->bcols,&flg);CHKERRQ(ierr);
38393dfae19SHong Zhang   if (flg && matfd->bcols > matfd->ncolors) {
38493dfae19SHong Zhang     /* input bcols cannot be > matfd->ncolors, thus set it as ncolors */
38593dfae19SHong Zhang     matfd->bcols = matfd->ncolors;
38693dfae19SHong Zhang   }
387f86b9fbaSHong Zhang 
3885d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
3895d973c19SBarry Smith   ierr = PetscObjectProcessOptionsHandlers((PetscObject)matfd);CHKERRQ(ierr);
390b0a32e0cSBarry Smith   PetscOptionsEnd();CHKERRQ(ierr);
3913a40ed3dSBarry Smith   PetscFunctionReturn(0);
392005c665bSBarry Smith }
393005c665bSBarry Smith 
3944a2ae208SSatish Balay #undef __FUNCT__
395e350db43SBarry Smith #define __FUNCT__ "MatFDColoringViewFromOptions"
396146574abSBarry Smith PetscErrorCode MatFDColoringViewFromOptions(MatFDColoring fd,const char prefix[],const char optionname[])
397005c665bSBarry Smith {
398dfbe8321SBarry Smith   PetscErrorCode    ierr;
399e350db43SBarry Smith   PetscBool         flg;
4003050cee2SBarry Smith   PetscViewer       viewer;
401cffb1e40SBarry Smith   PetscViewerFormat format;
402005c665bSBarry Smith 
4033a40ed3dSBarry Smith   PetscFunctionBegin;
404146574abSBarry Smith   if (prefix) {
405146574abSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)fd),prefix,optionname,&viewer,&format,&flg);CHKERRQ(ierr);
406146574abSBarry Smith   } else {
407ce94432eSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)fd),((PetscObject)fd)->prefix,optionname,&viewer,&format,&flg);CHKERRQ(ierr);
408146574abSBarry Smith   }
409005c665bSBarry Smith   if (flg) {
410cffb1e40SBarry Smith     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
4113050cee2SBarry Smith     ierr = MatFDColoringView(fd,viewer);CHKERRQ(ierr);
412cffb1e40SBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
413cffb1e40SBarry Smith     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
414005c665bSBarry Smith   }
4153a40ed3dSBarry Smith   PetscFunctionReturn(0);
416bbf0e169SBarry Smith }
417bbf0e169SBarry Smith 
4184a2ae208SSatish Balay #undef __FUNCT__
4194a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate"
42005869f15SSatish Balay /*@
421639f9d9dSBarry Smith    MatFDColoringCreate - Creates a matrix coloring context for finite difference
422639f9d9dSBarry Smith    computation of Jacobians.
423bbf0e169SBarry Smith 
424ef5ee4d1SLois Curfman McInnes    Collective on Mat
425ef5ee4d1SLois Curfman McInnes 
426639f9d9dSBarry Smith    Input Parameters:
427ef5ee4d1SLois Curfman McInnes +  mat - the matrix containing the nonzero structure of the Jacobian
4287086a01eSPeter Brune -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
429bbf0e169SBarry Smith 
430bbf0e169SBarry Smith     Output Parameter:
431639f9d9dSBarry Smith .   color - the new coloring context
432bbf0e169SBarry Smith 
43315091d37SBarry Smith     Level: intermediate
43415091d37SBarry Smith 
4358d359177SBarry Smith .seealso: MatFDColoringDestroy(),SNESComputeJacobianDefaultColor(), ISColoringCreate(),
436d1c39f55SBarry Smith           MatFDColoringSetFunction(), MatFDColoringSetFromOptions(), MatFDColoringApply(),
4377086a01eSPeter Brune           MatFDColoringView(), MatFDColoringSetParameters(), MatColoringCreate(), DMCreateColoring()
438bbf0e169SBarry Smith @*/
4397087cfbeSBarry Smith PetscErrorCode  MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color)
440bbf0e169SBarry Smith {
441639f9d9dSBarry Smith   MatFDColoring  c;
442639f9d9dSBarry Smith   MPI_Comm       comm;
443dfbe8321SBarry Smith   PetscErrorCode ierr;
44438baddfdSBarry Smith   PetscInt       M,N;
445639f9d9dSBarry Smith 
4463a40ed3dSBarry Smith   PetscFunctionBegin;
447c8a9c622SHong Zhang   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
448f141eedfSHong Zhang   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();");
449d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(MAT_FDColoringCreate,mat,0,0,0);CHKERRQ(ierr);
450639f9d9dSBarry Smith   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
451ce94432eSBarry Smith   if (M != N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Only for square matrices");
452f881d145SBarry Smith   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
45367c2884eSBarry Smith   ierr = PetscHeaderCreate(c,_p_MatFDColoring,int,MAT_FDCOLORING_CLASSID,"MatFDColoring","Jacobian computation via finite differences with coloring","Mat",comm,MatFDColoringDestroy,MatFDColoringView);CHKERRQ(ierr);
454639f9d9dSBarry Smith 
455b8f8c88eSHong Zhang   c->ctype = iscoloring->ctype;
456b8f8c88eSHong Zhang 
45793dfae19SHong Zhang   if (mat->ops->fdcoloringcreate) {
45893dfae19SHong Zhang     ierr = (*mat->ops->fdcoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
45993dfae19SHong Zhang   } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
46093dfae19SHong Zhang 
461f77a5242SKarl Rupp   ierr = MatGetVecs(mat,NULL,&c->w1);CHKERRQ(ierr);
4623bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)c,(PetscObject)c->w1);CHKERRQ(ierr);
463b8f8c88eSHong Zhang   ierr = VecDuplicate(c->w1,&c->w2);CHKERRQ(ierr);
4643bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)c,(PetscObject)c->w2);CHKERRQ(ierr);
465b8f8c88eSHong Zhang 
46677d8c4bbSBarry Smith   c->error_rel    = PETSC_SQRT_MACHINE_EPSILON;
46777d8c4bbSBarry Smith   c->umin         = 100.0*PETSC_SQRT_MACHINE_EPSILON;
46849b058dcSBarry Smith   c->currentcolor = -1;
469efb30889SBarry Smith   c->htype        = "wp";
4704e269d77SPeter Brune   c->fset         = PETSC_FALSE;
471c8a9c622SHong Zhang   c->setupcalled  = PETSC_FALSE;
472639f9d9dSBarry Smith 
473639f9d9dSBarry Smith   *color = c;
4744e269d77SPeter Brune   ierr   = PetscObjectCompose((PetscObject)mat,"SNESMatFDColoring",(PetscObject)c);CHKERRQ(ierr);
475d5ba7fb7SMatthew Knepley   ierr   = PetscLogEventEnd(MAT_FDColoringCreate,mat,0,0,0);CHKERRQ(ierr);
4763a40ed3dSBarry Smith   PetscFunctionReturn(0);
477bbf0e169SBarry Smith }
478bbf0e169SBarry Smith 
4794a2ae208SSatish Balay #undef __FUNCT__
4804a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringDestroy"
48105869f15SSatish Balay /*@
482639f9d9dSBarry Smith     MatFDColoringDestroy - Destroys a matrix coloring context that was created
483639f9d9dSBarry Smith     via MatFDColoringCreate().
484bbf0e169SBarry Smith 
485ef5ee4d1SLois Curfman McInnes     Collective on MatFDColoring
486ef5ee4d1SLois Curfman McInnes 
487b4fc646aSLois Curfman McInnes     Input Parameter:
488639f9d9dSBarry Smith .   c - coloring context
489bbf0e169SBarry Smith 
49015091d37SBarry Smith     Level: intermediate
49115091d37SBarry Smith 
492639f9d9dSBarry Smith .seealso: MatFDColoringCreate()
493bbf0e169SBarry Smith @*/
4946bf464f9SBarry Smith PetscErrorCode  MatFDColoringDestroy(MatFDColoring *c)
495bbf0e169SBarry Smith {
4966849ba73SBarry Smith   PetscErrorCode ierr;
49738baddfdSBarry Smith   PetscInt       i;
4980df34763SHong Zhang   MatFDColoring  color = *c;
499bbf0e169SBarry Smith 
5003a40ed3dSBarry Smith   PetscFunctionBegin;
5016bf464f9SBarry Smith   if (!*c) PetscFunctionReturn(0);
5020df34763SHong Zhang   if (--((PetscObject)color)->refct > 0) {*c = 0; PetscFunctionReturn(0);}
503d4bb536fSBarry Smith 
5040df34763SHong Zhang   for (i=0; i<color->ncolors; i++) {
5050df34763SHong Zhang     ierr = PetscFree(color->columns[i]);CHKERRQ(ierr);
506bbf0e169SBarry Smith   }
5070df34763SHong Zhang   ierr = PetscFree(color->ncolumns);CHKERRQ(ierr);
5080df34763SHong Zhang   ierr = PetscFree(color->columns);CHKERRQ(ierr);
5090df34763SHong Zhang   ierr = PetscFree(color->nrows);CHKERRQ(ierr);
5100df34763SHong Zhang   if (color->htype[0] == 'w') {
5110df34763SHong Zhang     ierr = PetscFree(color->matentry2);CHKERRQ(ierr);
5120df34763SHong Zhang   } else {
5130df34763SHong Zhang     ierr = PetscFree(color->matentry);CHKERRQ(ierr);
5140df34763SHong Zhang   }
5150df34763SHong Zhang   ierr = PetscFree(color->dy);CHKERRQ(ierr);
5160df34763SHong Zhang   if (color->vscale) {ierr = VecDestroy(&color->vscale);CHKERRQ(ierr);}
5170df34763SHong Zhang   ierr = VecDestroy(&color->w1);CHKERRQ(ierr);
5180df34763SHong Zhang   ierr = VecDestroy(&color->w2);CHKERRQ(ierr);
5190df34763SHong Zhang   ierr = VecDestroy(&color->w3);CHKERRQ(ierr);
520d38fa0fbSBarry Smith   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
5213a40ed3dSBarry Smith   PetscFunctionReturn(0);
522bbf0e169SBarry Smith }
52343a90d84SBarry Smith 
5244a2ae208SSatish Balay #undef __FUNCT__
52549b058dcSBarry Smith #define __FUNCT__ "MatFDColoringGetPerturbedColumns"
52649b058dcSBarry Smith /*@C
52749b058dcSBarry Smith     MatFDColoringGetPerturbedColumns - Returns the indices of the columns that
52849b058dcSBarry Smith       that are currently being perturbed.
52949b058dcSBarry Smith 
53049b058dcSBarry Smith     Not Collective
53149b058dcSBarry Smith 
53249b058dcSBarry Smith     Input Parameters:
53349b058dcSBarry Smith .   coloring - coloring context created with MatFDColoringCreate()
53449b058dcSBarry Smith 
53549b058dcSBarry Smith     Output Parameters:
53649b058dcSBarry Smith +   n - the number of local columns being perturbed
53749b058dcSBarry Smith -   cols - the column indices, in global numbering
53849b058dcSBarry Smith 
53949b058dcSBarry Smith    Level: intermediate
54049b058dcSBarry Smith 
54149b058dcSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView(), MatFDColoringApply()
54249b058dcSBarry Smith 
54349b058dcSBarry Smith .keywords: coloring, Jacobian, finite differences
54449b058dcSBarry Smith @*/
5457087cfbeSBarry Smith PetscErrorCode  MatFDColoringGetPerturbedColumns(MatFDColoring coloring,PetscInt *n,PetscInt *cols[])
54649b058dcSBarry Smith {
54749b058dcSBarry Smith   PetscFunctionBegin;
54849b058dcSBarry Smith   if (coloring->currentcolor >= 0) {
54949b058dcSBarry Smith     *n    = coloring->ncolumns[coloring->currentcolor];
55049b058dcSBarry Smith     *cols = coloring->columns[coloring->currentcolor];
55149b058dcSBarry Smith   } else {
55249b058dcSBarry Smith     *n = 0;
55349b058dcSBarry Smith   }
55449b058dcSBarry Smith   PetscFunctionReturn(0);
55549b058dcSBarry Smith }
55649b058dcSBarry Smith 
55749b058dcSBarry Smith #undef __FUNCT__
5584a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringApply"
55943a90d84SBarry Smith /*@
560e0907662SLois Curfman McInnes     MatFDColoringApply - Given a matrix for which a MatFDColoring context
561e0907662SLois Curfman McInnes     has been created, computes the Jacobian for a function via finite differences.
56243a90d84SBarry Smith 
563fee21e36SBarry Smith     Collective on MatFDColoring
564fee21e36SBarry Smith 
565ef5ee4d1SLois Curfman McInnes     Input Parameters:
566ef5ee4d1SLois Curfman McInnes +   mat - location to store Jacobian
567ef5ee4d1SLois Curfman McInnes .   coloring - coloring context created with MatFDColoringCreate()
568ef5ee4d1SLois Curfman McInnes .   x1 - location at which Jacobian is to be computed
5697850c7c0SBarry Smith -   sctx - context required by function, if this is being used with the SNES solver then it is SNES object, otherwise it is null
570ef5ee4d1SLois Curfman McInnes 
5718bba8e72SBarry Smith     Options Database Keys:
572ebd3b9afSBarry Smith +    -mat_fd_type - "wp" or "ds"  (see MATMFFD_WP or MATMFFD_DS)
573b9722508SLois Curfman McInnes .    -mat_fd_coloring_view - Activates basic viewing or coloring
574e350db43SBarry Smith .    -mat_fd_coloring_view draw - Activates drawing of coloring
575e350db43SBarry Smith -    -mat_fd_coloring_view ::ascii_info - Activates viewing of coloring info
5768bba8e72SBarry Smith 
57715091d37SBarry Smith     Level: intermediate
57898d79826SSatish Balay 
5797850c7c0SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView(), MatFDColoringSetFunction()
58043a90d84SBarry Smith 
58143a90d84SBarry Smith .keywords: coloring, Jacobian, finite differences
58243a90d84SBarry Smith @*/
583*d1e9a80fSBarry Smith PetscErrorCode  MatFDColoringApply(Mat J,MatFDColoring coloring,Vec x1,void *sctx)
58443a90d84SBarry Smith {
5853acb8795SBarry Smith   PetscErrorCode ierr;
586684f2004SHong Zhang   PetscBool      flg = PETSC_FALSE;
5873acb8795SBarry Smith 
5883acb8795SBarry Smith   PetscFunctionBegin;
5890700a824SBarry Smith   PetscValidHeaderSpecific(J,MAT_CLASSID,1);
5900700a824SBarry Smith   PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_CLASSID,2);
5910700a824SBarry Smith   PetscValidHeaderSpecific(x1,VEC_CLASSID,3);
592ce94432eSBarry Smith   if (!coloring->f) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetFunction()");
593e32f2f54SBarry Smith   if (!J->ops->fdcoloringapply) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)J)->type_name);
594c8a9c622SHong Zhang   if (!coloring->setupcalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetUp()");
595684f2004SHong Zhang 
596684f2004SHong Zhang   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
597684f2004SHong Zhang   ierr = PetscOptionsGetBool(NULL,"-mat_fd_coloring_dont_rezero",&flg,NULL);CHKERRQ(ierr);
598684f2004SHong Zhang   if (flg) {
599684f2004SHong Zhang     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
600684f2004SHong Zhang   } else {
601684f2004SHong Zhang     PetscBool assembled;
602684f2004SHong Zhang     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
603684f2004SHong Zhang     if (assembled) {
604684f2004SHong Zhang       ierr = MatZeroEntries(J);CHKERRQ(ierr);
605684f2004SHong Zhang     }
606684f2004SHong Zhang   }
607684f2004SHong Zhang 
6085922145eSHong Zhang   ierr = PetscLogEventBegin(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr);
609*d1e9a80fSBarry Smith   ierr = (*J->ops->fdcoloringapply)(J,coloring,x1,sctx);CHKERRQ(ierr);
6105922145eSHong Zhang   ierr = PetscLogEventEnd(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr);
6113acb8795SBarry Smith   PetscFunctionReturn(0);
6123acb8795SBarry Smith }
613