xref: /petsc/src/mat/matfd/fdmatrix.c (revision 77ed534321f0a860738694ee6d0aa216f0623125)
1840b8ebdSBarry Smith 
2a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
3*77ed5343SBarry Smith static char vcid[] = "$Id: fdmatrix.c,v 1.37 1998/10/06 03:23:20 bsmith Exp bsmith $";
4bbf0e169SBarry Smith #endif
5bbf0e169SBarry Smith 
6bbf0e169SBarry Smith /*
7639f9d9dSBarry Smith    This is where the abstract matrix operations are defined that are
8639f9d9dSBarry Smith   used for finite difference computations of Jacobians using coloring.
9bbf0e169SBarry Smith */
10bbf0e169SBarry Smith 
11bbf0e169SBarry Smith #include "petsc.h"
12bbf0e169SBarry Smith #include "src/mat/matimpl.h"        /*I "mat.h" I*/
13bbf0e169SBarry Smith #include "src/vec/vecimpl.h"
14bbf0e169SBarry Smith 
155615d1e5SSatish Balay #undef __FUNC__
16d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringView_Draw"
17005c665bSBarry Smith static int MatFDColoringView_Draw(MatFDColoring fd,Viewer viewer)
18005c665bSBarry Smith {
19005c665bSBarry Smith   int         ierr,i,j,pause;
20005c665bSBarry Smith   PetscTruth  isnull;
21005c665bSBarry Smith   Draw        draw;
22d4bb536fSBarry Smith   double      xr,yr,xl,yl,h,w,x,y,xc,yc,scale = 0.0;
23005c665bSBarry Smith   DrawButton  button;
24005c665bSBarry Smith 
253a40ed3dSBarry Smith   PetscFunctionBegin;
26*77ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw); CHKERRQ(ierr);
273a40ed3dSBarry Smith   ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
282bdab257SBarry Smith   ierr = DrawSynchronizedClear(draw); CHKERRQ(ierr);
29005c665bSBarry Smith 
30005c665bSBarry Smith   xr  = fd->N; yr = fd->M; h = yr/10.0; w = xr/10.0;
31005c665bSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
32005c665bSBarry Smith   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
33005c665bSBarry Smith 
34005c665bSBarry Smith   /* loop over colors  */
35005c665bSBarry Smith   for (i=0; i<fd->ncolors; i++ ) {
36005c665bSBarry Smith     for ( j=0; j<fd->nrows[i]; j++ ) {
37005c665bSBarry Smith       y = fd->M - fd->rows[i][j] - fd->rstart;
38005c665bSBarry Smith       x = fd->columnsforrow[i][j];
395cd90555SBarry Smith       ierr = DrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1); CHKERRQ(ierr);
40005c665bSBarry Smith     }
41005c665bSBarry Smith   }
422bdab257SBarry Smith   ierr = DrawSynchronizedFlush(draw); CHKERRQ(ierr);
43005c665bSBarry Smith   ierr = DrawGetPause(draw,&pause); CHKERRQ(ierr);
443a40ed3dSBarry Smith   if (pause >= 0) { PetscSleep(pause); PetscFunctionReturn(0);}
455cd90555SBarry Smith   ierr = DrawCheckResizedWindow(draw); CHKERRQ(ierr);
465cd90555SBarry Smith   ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);  CHKERRQ(ierr);
47005c665bSBarry Smith   while (button != BUTTON_RIGHT) {
482bdab257SBarry Smith     ierr = DrawSynchronizedClear(draw); CHKERRQ(ierr);
49005c665bSBarry Smith     if (button == BUTTON_LEFT) scale = .5;
50005c665bSBarry Smith     else if (button == BUTTON_CENTER) scale = 2.;
51005c665bSBarry Smith     xl = scale*(xl + w - xc) + xc - w*scale;
52005c665bSBarry Smith     xr = scale*(xr - w - xc) + xc + w*scale;
53005c665bSBarry Smith     yl = scale*(yl + h - yc) + yc - h*scale;
54005c665bSBarry Smith     yr = scale*(yr - h - yc) + yc + h*scale;
55005c665bSBarry Smith     w *= scale; h *= scale;
56005c665bSBarry Smith     ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
57005c665bSBarry Smith     /* loop over colors  */
58005c665bSBarry Smith     for (i=0; i<fd->ncolors; i++ ) {
59005c665bSBarry Smith       for ( j=0; j<fd->nrows[i]; j++ ) {
60005c665bSBarry Smith         y = fd->M - fd->rows[i][j] - fd->rstart;
61005c665bSBarry Smith         x = fd->columnsforrow[i][j];
625cd90555SBarry Smith         ierr = DrawRectangle(draw,x,y,x+1,y+1,i+1,i+1,i+1,i+1); CHKERRQ(ierr);
63005c665bSBarry Smith       }
64005c665bSBarry Smith     }
655cd90555SBarry Smith     ierr = DrawCheckResizedWindow(draw); CHKERRQ(ierr);
665cd90555SBarry Smith     ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);  CHKERRQ(ierr);
67005c665bSBarry Smith   }
68005c665bSBarry Smith 
693a40ed3dSBarry Smith   PetscFunctionReturn(0);
70005c665bSBarry Smith }
71005c665bSBarry Smith 
72005c665bSBarry Smith #undef __FUNC__
73d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringView"
74bbf0e169SBarry Smith /*@C
75639f9d9dSBarry Smith    MatFDColoringView - Views a finite difference coloring context.
76bbf0e169SBarry Smith 
77fee21e36SBarry Smith    Collective on MatFDColoring unless Viewer is VIEWER_STDOUT_SELF
78fee21e36SBarry Smith 
79ef5ee4d1SLois Curfman McInnes    Input  Parameters:
80ef5ee4d1SLois Curfman McInnes +  c - the coloring context
81ef5ee4d1SLois Curfman McInnes -  viewer - visualization context
82ef5ee4d1SLois Curfman McInnes 
83b4fc646aSLois Curfman McInnes    Notes:
84b4fc646aSLois Curfman McInnes    The available visualization contexts include
85ef5ee4d1SLois Curfman McInnes +     VIEWER_STDOUT_SELF - standard output (default)
86ef5ee4d1SLois Curfman McInnes .     VIEWER_STDOUT_WORLD - synchronized standard
87ef5ee4d1SLois Curfman McInnes         output where only the first processor opens
88ef5ee4d1SLois Curfman McInnes         the file.  All other processors send their
89ef5ee4d1SLois Curfman McInnes         data to the first processor to print.
90ef5ee4d1SLois Curfman McInnes -     VIEWER_DRAWX_WORLD - graphical display of nonzero structure
91bbf0e169SBarry Smith 
92639f9d9dSBarry Smith .seealso: MatFDColoringCreate()
93005c665bSBarry Smith 
94b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, view
95bbf0e169SBarry Smith @*/
96b4fc646aSLois Curfman McInnes int MatFDColoringView(MatFDColoring c,Viewer viewer)
97bbf0e169SBarry Smith {
98005c665bSBarry Smith   ViewerType vtype;
99639f9d9dSBarry Smith   int        i,j,format,ierr;
100b4fc646aSLois Curfman McInnes   FILE       *fd;
101bbf0e169SBarry Smith 
1023a40ed3dSBarry Smith   PetscFunctionBegin;
103b4fc646aSLois Curfman McInnes   PetscValidHeaderSpecific(c,MAT_FDCOLORING_COOKIE);
104b4fc646aSLois Curfman McInnes   if (viewer) {PetscValidHeader(viewer);}
105b4fc646aSLois Curfman McInnes   else {viewer = VIEWER_STDOUT_SELF;}
106bbf0e169SBarry Smith 
107005c665bSBarry Smith   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
108*77ed5343SBarry Smith   if (!PetscStrcmp(vtype,DRAW_VIEWER)) {
109b4fc646aSLois Curfman McInnes     ierr = MatFDColoringView_Draw(c,viewer); CHKERRQ(ierr);
1103a40ed3dSBarry Smith     PetscFunctionReturn(0);
111*77ed5343SBarry Smith   } else if (!PetscStrcmp(vtype,ASCII_VIEWER)) {
112b4fc646aSLois Curfman McInnes     ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
113b4fc646aSLois Curfman McInnes     PetscFPrintf(c->comm,fd,"MatFDColoring Object:\n");
114b4fc646aSLois Curfman McInnes     PetscFPrintf(c->comm,fd,"  Error tolerance=%g\n",c->error_rel);
115b4fc646aSLois Curfman McInnes     PetscFPrintf(c->comm,fd,"  Umin=%g\n",c->umin);
116b4fc646aSLois Curfman McInnes     PetscFPrintf(c->comm,fd,"  Number of colors=%d\n",c->ncolors);
117ae09f205SBarry Smith 
118ae09f205SBarry Smith     ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr);
119ae09f205SBarry Smith     if (format != VIEWER_FORMAT_ASCII_INFO) {
120b4fc646aSLois Curfman McInnes       for ( i=0; i<c->ncolors; i++ ) {
121b4fc646aSLois Curfman McInnes         PetscFPrintf(c->comm,fd,"  Information for color %d\n",i);
122b4fc646aSLois Curfman McInnes         PetscFPrintf(c->comm,fd,"    Number of columns %d\n",c->ncolumns[i]);
123b4fc646aSLois Curfman McInnes         for ( j=0; j<c->ncolumns[i]; j++ ) {
124b4fc646aSLois Curfman McInnes           PetscFPrintf(c->comm,fd,"      %d\n",c->columns[i][j]);
125639f9d9dSBarry Smith         }
126b4fc646aSLois Curfman McInnes         PetscFPrintf(c->comm,fd,"    Number of rows %d\n",c->nrows[i]);
127b4fc646aSLois Curfman McInnes         for ( j=0; j<c->nrows[i]; j++ ) {
128b4fc646aSLois Curfman McInnes           PetscFPrintf(c->comm,fd,"      %d %d \n",c->rows[i][j],c->columnsforrow[i][j]);
129b4fc646aSLois Curfman McInnes         }
130bbf0e169SBarry Smith       }
131bbf0e169SBarry Smith     }
1325cd90555SBarry Smith   } else {
1335cd90555SBarry Smith     SETERRQ(1,1,"Viewer type not supported for this object");
134bbf0e169SBarry Smith   }
1353a40ed3dSBarry Smith   PetscFunctionReturn(0);
136639f9d9dSBarry Smith }
137639f9d9dSBarry Smith 
1385615d1e5SSatish Balay #undef __FUNC__
1395615d1e5SSatish Balay #define __FUNC__ "MatFDColoringSetParameters"
140639f9d9dSBarry Smith /*@
141b4fc646aSLois Curfman McInnes    MatFDColoringSetParameters - Sets the parameters for the sparse approximation of
142b4fc646aSLois Curfman McInnes    a Jacobian matrix using finite differences.
143639f9d9dSBarry Smith 
144ef5ee4d1SLois Curfman McInnes    Collective on MatFDColoring
145ef5ee4d1SLois Curfman McInnes 
146ef5ee4d1SLois Curfman McInnes    The Jacobian is estimated with the differencing approximation
147ef5ee4d1SLois Curfman McInnes .vb
148ef5ee4d1SLois Curfman McInnes        J(u)_{:,i} = [J(u+h*dx_{i}) - J(u)]/h where
149f23b5b22SLois Curfman McInnes        h = error_rel*u[i]                 if  abs(u[i]) > umin
150f23b5b22SLois Curfman McInnes          = +/- error_rel*umin             otherwise, with +/- determined by the sign of u[i]
151ef5ee4d1SLois Curfman McInnes        dx_{i} = (0, ... 1, .... 0)
152ef5ee4d1SLois Curfman McInnes .ve
153639f9d9dSBarry Smith 
154639f9d9dSBarry Smith    Input Parameters:
155ef5ee4d1SLois Curfman McInnes +  coloring - the coloring context
156639f9d9dSBarry Smith .  error_rel - relative error
157f23b5b22SLois Curfman McInnes -  umin - minimum allowable u-value magnitude
158fee21e36SBarry Smith 
159b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, parameters
160b4fc646aSLois Curfman McInnes 
161b4fc646aSLois Curfman McInnes .seealso: MatFDColoringCreate()
162639f9d9dSBarry Smith @*/
163639f9d9dSBarry Smith int MatFDColoringSetParameters(MatFDColoring matfd,double error,double umin)
164639f9d9dSBarry Smith {
1653a40ed3dSBarry Smith   PetscFunctionBegin;
166639f9d9dSBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE);
167639f9d9dSBarry Smith 
168639f9d9dSBarry Smith   if (error != PETSC_DEFAULT) matfd->error_rel = error;
169639f9d9dSBarry Smith   if (umin != PETSC_DEFAULT)  matfd->umin      = umin;
1703a40ed3dSBarry Smith   PetscFunctionReturn(0);
171639f9d9dSBarry Smith }
172639f9d9dSBarry Smith 
1735615d1e5SSatish Balay #undef __FUNC__
174005c665bSBarry Smith #define __FUNC__ "MatFDColoringSetFrequency"
175005c665bSBarry Smith /*@
176e0907662SLois Curfman McInnes    MatFDColoringSetFrequency - Sets the frequency for computing new Jacobian
177e0907662SLois Curfman McInnes    matrices.
178005c665bSBarry Smith 
179fee21e36SBarry Smith    Collective on MatFDColoring
180fee21e36SBarry Smith 
181ef5ee4d1SLois Curfman McInnes    Input Parameters:
182ef5ee4d1SLois Curfman McInnes +  coloring - the coloring context
183ef5ee4d1SLois Curfman McInnes -  freq - frequency (default is 1)
184ef5ee4d1SLois Curfman McInnes 
185e0907662SLois Curfman McInnes    Notes:
186e0907662SLois Curfman McInnes    Using a modified Newton strategy, where the Jacobian remains fixed for several
187e0907662SLois Curfman McInnes    iterations, can be cost effective in terms of overall nonlinear solution
188e0907662SLois Curfman McInnes    efficiency.  This parameter indicates that a new Jacobian will be computed every
189e0907662SLois Curfman McInnes    <freq> nonlinear iterations.
190e0907662SLois Curfman McInnes 
191e0907662SLois Curfman McInnes    Options Database Keys:
192ef5ee4d1SLois Curfman McInnes .  -mat_fd_coloring_freq <freq>  - Sets coloring frequency
193005c665bSBarry Smith 
194b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, coloring, set, frequency
195ef5ee4d1SLois Curfman McInnes 
196ef5ee4d1SLois Curfman McInnes .seealso: MatFDColoringCreate(), MatFDColoringGetFrequency()
197005c665bSBarry Smith @*/
198005c665bSBarry Smith int MatFDColoringSetFrequency(MatFDColoring matfd,int freq)
199005c665bSBarry Smith {
2003a40ed3dSBarry Smith   PetscFunctionBegin;
201005c665bSBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE);
202005c665bSBarry Smith 
203005c665bSBarry Smith   matfd->freq = freq;
2043a40ed3dSBarry Smith   PetscFunctionReturn(0);
205005c665bSBarry Smith }
206005c665bSBarry Smith 
207005c665bSBarry Smith #undef __FUNC__
208ff0cfa39SBarry Smith #define __FUNC__ "MatFDColoringGetFrequency"
209ff0cfa39SBarry Smith /*@
210ff0cfa39SBarry Smith    MatFDColoringGetFrequency - Gets the frequency for computing new Jacobian
211ff0cfa39SBarry Smith    matrices.
212ff0cfa39SBarry Smith 
213ef5ee4d1SLois Curfman McInnes    Not Collective
214ef5ee4d1SLois Curfman McInnes 
215ff0cfa39SBarry Smith    Input Parameters:
216ff0cfa39SBarry Smith .  coloring - the coloring context
217ff0cfa39SBarry Smith 
218ff0cfa39SBarry Smith    Output Parameters:
219ff0cfa39SBarry Smith .  freq - frequency (default is 1)
220ff0cfa39SBarry Smith 
221ff0cfa39SBarry Smith    Notes:
222ff0cfa39SBarry Smith    Using a modified Newton strategy, where the Jacobian remains fixed for several
223ff0cfa39SBarry Smith    iterations, can be cost effective in terms of overall nonlinear solution
224ff0cfa39SBarry Smith    efficiency.  This parameter indicates that a new Jacobian will be computed every
225ff0cfa39SBarry Smith    <freq> nonlinear iterations.
226ff0cfa39SBarry Smith 
227ff0cfa39SBarry Smith    Options Database Keys:
228ef5ee4d1SLois Curfman McInnes .  -mat_fd_coloring_freq <freq> - Sets coloring frequency
229ff0cfa39SBarry Smith 
230ff0cfa39SBarry Smith .keywords: Mat, finite differences, coloring, get, frequency
231ef5ee4d1SLois Curfman McInnes 
232ef5ee4d1SLois Curfman McInnes .seealso: MatFDColoringSetFrequency()
233ff0cfa39SBarry Smith @*/
234ff0cfa39SBarry Smith int MatFDColoringGetFrequency(MatFDColoring matfd,int *freq)
235ff0cfa39SBarry Smith {
2363a40ed3dSBarry Smith   PetscFunctionBegin;
237ff0cfa39SBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE);
238ff0cfa39SBarry Smith 
239ff0cfa39SBarry Smith   *freq = matfd->freq;
2403a40ed3dSBarry Smith   PetscFunctionReturn(0);
241ff0cfa39SBarry Smith }
242ff0cfa39SBarry Smith 
243ff0cfa39SBarry Smith #undef __FUNC__
244005c665bSBarry Smith #define __FUNC__ "MatFDColoringSetFunction"
245d64ed03dSBarry Smith /*@C
246005c665bSBarry Smith    MatFDColoringSetFunction - Sets the function to use for computing the Jacobian.
247005c665bSBarry Smith 
248fee21e36SBarry Smith    Collective on MatFDColoring
249fee21e36SBarry Smith 
250ef5ee4d1SLois Curfman McInnes    Input Parameters:
251ef5ee4d1SLois Curfman McInnes +  coloring - the coloring context
252ef5ee4d1SLois Curfman McInnes .  f - the function
253ef5ee4d1SLois Curfman McInnes -  fctx - the optional user-defined function context
254ef5ee4d1SLois Curfman McInnes 
255b4fc646aSLois Curfman McInnes .keywords: Mat, Jacobian, finite differences, set, function
256005c665bSBarry Smith @*/
257840b8ebdSBarry Smith int MatFDColoringSetFunction(MatFDColoring matfd,int (*f)(void),void *fctx)
258005c665bSBarry Smith {
2593a40ed3dSBarry Smith   PetscFunctionBegin;
260005c665bSBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE);
261005c665bSBarry Smith 
262005c665bSBarry Smith   matfd->f    = f;
263005c665bSBarry Smith   matfd->fctx = fctx;
264005c665bSBarry Smith 
2653a40ed3dSBarry Smith   PetscFunctionReturn(0);
266005c665bSBarry Smith }
267005c665bSBarry Smith 
268005c665bSBarry Smith #undef __FUNC__
269d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringSetFromOptions"
270639f9d9dSBarry Smith /*@
271b4fc646aSLois Curfman McInnes    MatFDColoringSetFromOptions - Sets coloring finite difference parameters from
272639f9d9dSBarry Smith    the options database.
273639f9d9dSBarry Smith 
274fee21e36SBarry Smith    Collective on MatFDColoring
275fee21e36SBarry Smith 
276ef5ee4d1SLois Curfman McInnes    The Jacobian is estimated with the differencing approximation
277ef5ee4d1SLois Curfman McInnes .vb
278ef5ee4d1SLois Curfman McInnes        J(u)_{:,i} = [J(u+h*dx_{i}) - J(u)]/h where
279f23b5b22SLois Curfman McInnes        h = error_rel*u[i]                 if  abs(u[i]) > umin
280f23b5b22SLois Curfman McInnes          = +/- error_rel*umin             otherwise, with +/- determined by the sign of u[i]
281ef5ee4d1SLois Curfman McInnes        dx_{i} = (0, ... 1, .... 0)
282ef5ee4d1SLois Curfman McInnes .ve
283ef5ee4d1SLois Curfman McInnes 
284ef5ee4d1SLois Curfman McInnes    Input Parameter:
285ef5ee4d1SLois Curfman McInnes .  coloring - the coloring context
286ef5ee4d1SLois Curfman McInnes 
287b4fc646aSLois Curfman McInnes    Options Database Keys:
288ef5ee4d1SLois Curfman McInnes +  -mat_fd_coloring_error <err> - Sets <err> (square root
289ef5ee4d1SLois Curfman McInnes            of relative error in the function)
290f23b5b22SLois Curfman McInnes .  -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude
291ef5ee4d1SLois Curfman McInnes .  -mat_fd_coloring_freq <freq> - Sets frequency of computing a new Jacobian
292ef5ee4d1SLois Curfman McInnes .  -mat_fd_coloring_view - Activates basic viewing
293ef5ee4d1SLois Curfman McInnes .  -mat_fd_coloring_view_info - Activates viewing info
294ef5ee4d1SLois Curfman McInnes -  -mat_fd_coloring_view_draw - Activates drawing
295639f9d9dSBarry Smith 
296b4fc646aSLois Curfman McInnes .keywords: Mat, finite differences, parameters
297639f9d9dSBarry Smith @*/
298639f9d9dSBarry Smith int MatFDColoringSetFromOptions(MatFDColoring matfd)
299639f9d9dSBarry Smith {
300005c665bSBarry Smith   int    ierr,flag,freq = 1;
301639f9d9dSBarry Smith   double error = PETSC_DEFAULT,umin = PETSC_DEFAULT;
3023a40ed3dSBarry Smith 
3033a40ed3dSBarry Smith   PetscFunctionBegin;
304639f9d9dSBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE);
305639f9d9dSBarry Smith 
306639f9d9dSBarry Smith   ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_err",&error,&flag);CHKERRQ(ierr);
307639f9d9dSBarry Smith   ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_umin",&umin,&flag);CHKERRQ(ierr);
308639f9d9dSBarry Smith   ierr = MatFDColoringSetParameters(matfd,error,umin); CHKERRQ(ierr);
309005c665bSBarry Smith   ierr = OptionsGetInt(matfd->prefix,"-mat_fd_coloring_freq",&freq,&flag);CHKERRQ(ierr);
310005c665bSBarry Smith   ierr = MatFDColoringSetFrequency(matfd,freq);CHKERRQ(ierr);
311005c665bSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help",&flag); CHKERRQ(ierr);
312639f9d9dSBarry Smith   if (flag) {
313639f9d9dSBarry Smith     ierr = MatFDColoringPrintHelp(matfd); CHKERRQ(ierr);
314639f9d9dSBarry Smith   }
3153a40ed3dSBarry Smith   PetscFunctionReturn(0);
316639f9d9dSBarry Smith }
317639f9d9dSBarry Smith 
3185615d1e5SSatish Balay #undef __FUNC__
319d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringPrintHelp"
320639f9d9dSBarry Smith /*@
321639f9d9dSBarry Smith     MatFDColoringPrintHelp - Prints help message for matrix finite difference calculations
322639f9d9dSBarry Smith     using coloring.
323639f9d9dSBarry Smith 
324ef5ee4d1SLois Curfman McInnes     Collective on MatFDColoring
325ef5ee4d1SLois Curfman McInnes 
326639f9d9dSBarry Smith     Input Parameter:
327639f9d9dSBarry Smith .   fdcoloring - the MatFDColoring context
328639f9d9dSBarry Smith 
329639f9d9dSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringSetFromOptions()
330639f9d9dSBarry Smith @*/
331639f9d9dSBarry Smith int MatFDColoringPrintHelp(MatFDColoring fd)
332639f9d9dSBarry Smith {
3333a40ed3dSBarry Smith   PetscFunctionBegin;
334639f9d9dSBarry Smith   PetscValidHeaderSpecific(fd,MAT_FDCOLORING_COOKIE);
335639f9d9dSBarry Smith 
33676be9ce4SBarry Smith   (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_err <err>: set sqrt rel tol in function, defaults to %g\n",fd->error_rel);
33776be9ce4SBarry Smith   (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_umin <umin>: see users manual, defaults to %d\n",fd->umin);
33876be9ce4SBarry Smith   (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_freq <freq>: frequency that Jacobian is recomputed, defaults to %d\n",fd->freq);
33976be9ce4SBarry Smith   (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view\n");
34076be9ce4SBarry Smith   (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view_draw\n");
34176be9ce4SBarry Smith   (*PetscHelpPrintf)(fd->comm,"-mat_fd_coloring_view_info\n");
3423a40ed3dSBarry Smith   PetscFunctionReturn(0);
343005c665bSBarry Smith }
344005c665bSBarry Smith 
345005c665bSBarry Smith int MatFDColoringView_Private(MatFDColoring fd)
346005c665bSBarry Smith {
347005c665bSBarry Smith   int ierr,flg;
348005c665bSBarry Smith 
3493a40ed3dSBarry Smith   PetscFunctionBegin;
350005c665bSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view",&flg); CHKERRQ(ierr);
351005c665bSBarry Smith   if (flg) {
352f8590f6eSBarry Smith     ierr = MatFDColoringView(fd,VIEWER_STDOUT_(fd->comm)); CHKERRQ(ierr);
353005c665bSBarry Smith   }
354ae09f205SBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view_info",&flg); CHKERRQ(ierr);
355ae09f205SBarry Smith   if (flg) {
356f8590f6eSBarry Smith     ierr = ViewerPushFormat(VIEWER_STDOUT_(fd->comm),VIEWER_FORMAT_ASCII_INFO,PETSC_NULL);CHKERRQ(ierr);
357f8590f6eSBarry Smith     ierr = MatFDColoringView(fd,VIEWER_STDOUT_(fd->comm)); CHKERRQ(ierr);
358f8590f6eSBarry Smith     ierr = ViewerPopFormat(VIEWER_STDOUT_(fd->comm));CHKERRQ(ierr);
359ae09f205SBarry Smith   }
360005c665bSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_view_draw",&flg); CHKERRQ(ierr);
361005c665bSBarry Smith   if (flg) {
362005c665bSBarry Smith     ierr = MatFDColoringView(fd,VIEWER_DRAWX_(fd->comm)); CHKERRQ(ierr);
363005c665bSBarry Smith     ierr = ViewerFlush(VIEWER_DRAWX_(fd->comm)); CHKERRQ(ierr);
364005c665bSBarry Smith   }
3653a40ed3dSBarry Smith   PetscFunctionReturn(0);
366bbf0e169SBarry Smith }
367bbf0e169SBarry Smith 
3685615d1e5SSatish Balay #undef __FUNC__
3695615d1e5SSatish Balay #define __FUNC__ "MatFDColoringCreate"
370bbf0e169SBarry Smith /*@C
371639f9d9dSBarry Smith    MatFDColoringCreate - Creates a matrix coloring context for finite difference
372639f9d9dSBarry Smith    computation of Jacobians.
373bbf0e169SBarry Smith 
374ef5ee4d1SLois Curfman McInnes    Collective on Mat
375ef5ee4d1SLois Curfman McInnes 
376639f9d9dSBarry Smith    Input Parameters:
377ef5ee4d1SLois Curfman McInnes +  mat - the matrix containing the nonzero structure of the Jacobian
378ef5ee4d1SLois Curfman McInnes -  iscoloring - the coloring of the matrix
379bbf0e169SBarry Smith 
380bbf0e169SBarry Smith     Output Parameter:
381639f9d9dSBarry Smith .   color - the new coloring context
382bbf0e169SBarry Smith 
383b4fc646aSLois Curfman McInnes     Options Database Keys:
384ef5ee4d1SLois Curfman McInnes +    -mat_fd_coloring_view - Activates basic viewing or coloring
385ef5ee4d1SLois Curfman McInnes .    -mat_fd_coloring_view_draw - Activates drawing of coloring
386ef5ee4d1SLois Curfman McInnes -    -mat_fd_coloring_view_info - Activates viewing of coloring info
387639f9d9dSBarry Smith 
388639f9d9dSBarry Smith .seealso: MatFDColoringDestroy()
389bbf0e169SBarry Smith @*/
390639f9d9dSBarry Smith int MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color)
391bbf0e169SBarry Smith {
392639f9d9dSBarry Smith   MatFDColoring c;
393639f9d9dSBarry Smith   MPI_Comm      comm;
394639f9d9dSBarry Smith   int           ierr,M,N;
395639f9d9dSBarry Smith 
3963a40ed3dSBarry Smith   PetscFunctionBegin;
397639f9d9dSBarry Smith   ierr = MatGetSize(mat,&M,&N); CHKERRQ(ierr);
398e3372554SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Only for square matrices");
399639f9d9dSBarry Smith 
400639f9d9dSBarry Smith   PetscObjectGetComm((PetscObject)mat,&comm);
401f830108cSBarry Smith   PetscHeaderCreate(c,_p_MatFDColoring,int,MAT_FDCOLORING_COOKIE,0,comm,MatFDColoringDestroy,MatFDColoringView);
402639f9d9dSBarry Smith   PLogObjectCreate(c);
403639f9d9dSBarry Smith 
404f830108cSBarry Smith   if (mat->ops->fdcoloringcreate) {
405f830108cSBarry Smith     ierr = (*mat->ops->fdcoloringcreate)(mat,iscoloring,c); CHKERRQ(ierr);
406639f9d9dSBarry Smith   } else {
407e3372554SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Code not yet written for this matrix type");
408639f9d9dSBarry Smith   }
409639f9d9dSBarry Smith 
410639f9d9dSBarry Smith   c->error_rel = 1.e-8;
411ae09f205SBarry Smith   c->umin      = 1.e-6;
412005c665bSBarry Smith   c->freq      = 1;
413005c665bSBarry Smith 
414005c665bSBarry Smith   ierr = MatFDColoringView_Private(c); CHKERRQ(ierr);
415639f9d9dSBarry Smith 
416639f9d9dSBarry Smith   *color = c;
417639f9d9dSBarry Smith 
4183a40ed3dSBarry Smith   PetscFunctionReturn(0);
419bbf0e169SBarry Smith }
420bbf0e169SBarry Smith 
4215615d1e5SSatish Balay #undef __FUNC__
422d4bb536fSBarry Smith #define __FUNC__ "MatFDColoringDestroy"
423bbf0e169SBarry Smith /*@C
424639f9d9dSBarry Smith     MatFDColoringDestroy - Destroys a matrix coloring context that was created
425639f9d9dSBarry Smith     via MatFDColoringCreate().
426bbf0e169SBarry Smith 
427ef5ee4d1SLois Curfman McInnes     Collective on MatFDColoring
428ef5ee4d1SLois Curfman McInnes 
429b4fc646aSLois Curfman McInnes     Input Parameter:
430639f9d9dSBarry Smith .   c - coloring context
431bbf0e169SBarry Smith 
432639f9d9dSBarry Smith .seealso: MatFDColoringCreate()
433bbf0e169SBarry Smith @*/
434639f9d9dSBarry Smith int MatFDColoringDestroy(MatFDColoring c)
435bbf0e169SBarry Smith {
436263760aaSBarry Smith   int i,ierr;
437bbf0e169SBarry Smith 
4383a40ed3dSBarry Smith   PetscFunctionBegin;
4393a40ed3dSBarry Smith   if (--c->refct > 0) PetscFunctionReturn(0);
440d4bb536fSBarry Smith 
441639f9d9dSBarry Smith 
442639f9d9dSBarry Smith   for ( i=0; i<c->ncolors; i++ ) {
443639f9d9dSBarry Smith     if (c->columns[i])       PetscFree(c->columns[i]);
444639f9d9dSBarry Smith     if (c->rows[i])          PetscFree(c->rows[i]);
445639f9d9dSBarry Smith     if (c->columnsforrow[i]) PetscFree(c->columnsforrow[i]);
446bbf0e169SBarry Smith   }
447639f9d9dSBarry Smith   PetscFree(c->ncolumns);
448639f9d9dSBarry Smith   PetscFree(c->columns);
449639f9d9dSBarry Smith   PetscFree(c->nrows);
450639f9d9dSBarry Smith   PetscFree(c->rows);
451639f9d9dSBarry Smith   PetscFree(c->columnsforrow);
452639f9d9dSBarry Smith   PetscFree(c->scale);
453005c665bSBarry Smith   if (c->w1) {
454005c665bSBarry Smith     ierr = VecDestroy(c->w1); CHKERRQ(ierr);
455005c665bSBarry Smith     ierr = VecDestroy(c->w2); CHKERRQ(ierr);
456005c665bSBarry Smith     ierr = VecDestroy(c->w3); CHKERRQ(ierr);
457005c665bSBarry Smith   }
458639f9d9dSBarry Smith   PLogObjectDestroy(c);
459639f9d9dSBarry Smith   PetscHeaderDestroy(c);
4603a40ed3dSBarry Smith   PetscFunctionReturn(0);
461bbf0e169SBarry Smith }
46243a90d84SBarry Smith 
463005c665bSBarry Smith #include "snes.h"
464005c665bSBarry Smith 
4655615d1e5SSatish Balay #undef __FUNC__
4665615d1e5SSatish Balay #define __FUNC__ "MatFDColoringApply"
46743a90d84SBarry Smith /*@
468e0907662SLois Curfman McInnes     MatFDColoringApply - Given a matrix for which a MatFDColoring context
469e0907662SLois Curfman McInnes     has been created, computes the Jacobian for a function via finite differences.
47043a90d84SBarry Smith 
471fee21e36SBarry Smith     Collective on MatFDColoring
472fee21e36SBarry Smith 
473ef5ee4d1SLois Curfman McInnes     Input Parameters:
474ef5ee4d1SLois Curfman McInnes +   mat - location to store Jacobian
475ef5ee4d1SLois Curfman McInnes .   coloring - coloring context created with MatFDColoringCreate()
476ef5ee4d1SLois Curfman McInnes .   x1 - location at which Jacobian is to be computed
477ef5ee4d1SLois Curfman McInnes -   sctx - optional context required by function (actually a SNES context)
478ef5ee4d1SLois Curfman McInnes 
4798bba8e72SBarry Smith    Options Database Keys:
480ef5ee4d1SLois Curfman McInnes .  -mat_fd_coloring_freq <freq> - Sets coloring frequency
4818bba8e72SBarry Smith 
48243a90d84SBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView()
48343a90d84SBarry Smith 
48443a90d84SBarry Smith .keywords: coloring, Jacobian, finite differences
48543a90d84SBarry Smith @*/
486005c665bSBarry Smith int MatFDColoringApply(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
48743a90d84SBarry Smith {
488e0907662SLois Curfman McInnes   int           k,fg,ierr,N,start,end,l,row,col,srow;
48943a90d84SBarry Smith   Scalar        dx, mone = -1.0,*y,*scale = coloring->scale,*xx,*wscale = coloring->wscale;
49043a90d84SBarry Smith   double        epsilon = coloring->error_rel, umin = coloring->umin;
49143a90d84SBarry Smith   MPI_Comm      comm = coloring->comm;
492005c665bSBarry Smith   Vec           w1,w2,w3;
493840b8ebdSBarry Smith   int           (*f)(void *,Vec,Vec,void *) = ( int (*)(void *,Vec,Vec,void *))coloring->f;
494005c665bSBarry Smith   void          *fctx = coloring->fctx;
495005c665bSBarry Smith 
4963a40ed3dSBarry Smith   PetscFunctionBegin;
497e0907662SLois Curfman McInnes   PetscValidHeaderSpecific(J,MAT_COOKIE);
498e0907662SLois Curfman McInnes   PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_COOKIE);
499e0907662SLois Curfman McInnes   PetscValidHeaderSpecific(x1,VEC_COOKIE);
500e0907662SLois Curfman McInnes 
501005c665bSBarry Smith 
502005c665bSBarry Smith   if (!coloring->w1) {
503005c665bSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1); CHKERRQ(ierr);
504005c665bSBarry Smith     PLogObjectParent(coloring,coloring->w1);
505005c665bSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2); CHKERRQ(ierr);
506005c665bSBarry Smith     PLogObjectParent(coloring,coloring->w2);
507005c665bSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3); CHKERRQ(ierr);
508005c665bSBarry Smith     PLogObjectParent(coloring,coloring->w3);
509005c665bSBarry Smith   }
510005c665bSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
51143a90d84SBarry Smith 
512e0907662SLois Curfman McInnes   ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&fg); CHKERRQ(ierr);
513e0907662SLois Curfman McInnes   if (fg) {
514e0907662SLois Curfman McInnes     PLogInfo(coloring,"MatFDColoringApply: Not calling MatZeroEntries()\n");
515e0907662SLois Curfman McInnes   } else {
51643a90d84SBarry Smith     ierr = MatZeroEntries(J); CHKERRQ(ierr);
517e0907662SLois Curfman McInnes   }
51843a90d84SBarry Smith 
51943a90d84SBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end); CHKERRQ(ierr);
52043a90d84SBarry Smith   ierr = VecGetSize(x1,&N); CHKERRQ(ierr);
52143a90d84SBarry Smith   ierr = (*f)(sctx,x1,w1,fctx); CHKERRQ(ierr);
52243a90d84SBarry Smith 
52343a90d84SBarry Smith   PetscMemzero(wscale,N*sizeof(Scalar));
52443a90d84SBarry Smith   /*
52543a90d84SBarry Smith       Loop over each color
52643a90d84SBarry Smith   */
52743a90d84SBarry Smith 
5283b28642cSBarry Smith   ierr = VecGetArray(x1,&xx); CHKERRQ(ierr);
52943a90d84SBarry Smith   for (k=0; k<coloring->ncolors; k++) {
53043a90d84SBarry Smith     ierr = VecCopy(x1,w3); CHKERRQ(ierr);
53143a90d84SBarry Smith     /*
53243a90d84SBarry Smith        Loop over each column associated with color adding the
53343a90d84SBarry Smith        perturbation to the vector w3.
53443a90d84SBarry Smith     */
53543a90d84SBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
53643a90d84SBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
53743a90d84SBarry Smith       dx  = xx[col-start];
538ae09f205SBarry Smith       if (dx == 0.0) dx = 1.0;
5393a40ed3dSBarry Smith #if !defined(USE_PETSC_COMPLEX)
540ae09f205SBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
541ae09f205SBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
54243a90d84SBarry Smith #else
543e20fef11SSatish Balay       if (PetscAbsScalar(dx) < umin && PetscReal(dx) >= 0.0)     dx = umin;
544e20fef11SSatish Balay       else if (PetscReal(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
54543a90d84SBarry Smith #endif
54643a90d84SBarry Smith       dx          *= epsilon;
54743a90d84SBarry Smith       wscale[col] = 1.0/dx;
5483b28642cSBarry Smith       ierr = VecSetValues(w3,1,&col,&dx,ADD_VALUES);CHKERRQ(ierr);
54943a90d84SBarry Smith     }
5503b28642cSBarry Smith 
55143a90d84SBarry Smith     /*
552e0907662SLois Curfman McInnes        Evaluate function at x1 + dx (here dx is a vector of perturbations)
55343a90d84SBarry Smith     */
55443a90d84SBarry Smith     ierr = (*f)(sctx,w3,w2,fctx); CHKERRQ(ierr);
55543a90d84SBarry Smith     ierr = VecAXPY(&mone,w1,w2); CHKERRQ(ierr);
55643a90d84SBarry Smith     /* Communicate scale to all processors */
5573a40ed3dSBarry Smith #if !defined(USE_PETSC_COMPLEX)
558ca161407SBarry Smith     ierr = MPI_Allreduce(wscale,scale,N,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr);
55943a90d84SBarry Smith #else
560ca161407SBarry Smith     ierr = MPI_Allreduce(wscale,scale,2*N,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr);
56143a90d84SBarry Smith #endif
56243a90d84SBarry Smith     /*
563e0907662SLois Curfman McInnes        Loop over rows of vector, putting results into Jacobian matrix
56443a90d84SBarry Smith     */
5653b28642cSBarry Smith     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
56643a90d84SBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
56743a90d84SBarry Smith       row    = coloring->rows[k][l];
56843a90d84SBarry Smith       col    = coloring->columnsforrow[k][l];
56943a90d84SBarry Smith       y[row] *= scale[col];
57043a90d84SBarry Smith       srow   = row + start;
57143a90d84SBarry Smith       ierr   = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
57243a90d84SBarry Smith     }
5733b28642cSBarry Smith     ierr = VecRestoreArray(w2,&y); CHKERRQ(ierr);
57443a90d84SBarry Smith   }
5753b28642cSBarry Smith   ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
57643a90d84SBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
57743a90d84SBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
5783a40ed3dSBarry Smith   PetscFunctionReturn(0);
57943a90d84SBarry Smith }
580840b8ebdSBarry Smith 
581840b8ebdSBarry Smith #include "ts.h"
582840b8ebdSBarry Smith 
583840b8ebdSBarry Smith #undef __FUNC__
584840b8ebdSBarry Smith #define __FUNC__ "MatFDColoringApplyTS"
585840b8ebdSBarry Smith /*@
586840b8ebdSBarry Smith     MatFDColoringApplyTS - Given a matrix for which a MatFDColoring context
587840b8ebdSBarry Smith     has been created, computes the Jacobian for a function via finite differences.
588840b8ebdSBarry Smith 
589fee21e36SBarry Smith    Collective on Mat, MatFDColoring, and Vec
590fee21e36SBarry Smith 
591ef5ee4d1SLois Curfman McInnes     Input Parameters:
5923b28642cSBarry Smith +   mat - location to store Jacobian
593ef5ee4d1SLois Curfman McInnes .   coloring - coloring context created with MatFDColoringCreate()
594ef5ee4d1SLois Curfman McInnes .   x1 - location at which Jacobian is to be computed
595ef5ee4d1SLois Curfman McInnes -   sctx - optional context required by function (actually a SNES context)
596ef5ee4d1SLois Curfman McInnes 
597840b8ebdSBarry Smith    Options Database Keys:
598ef5ee4d1SLois Curfman McInnes .  -mat_fd_coloring_freq <freq> - Sets coloring frequency
599840b8ebdSBarry Smith 
600840b8ebdSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringView()
601840b8ebdSBarry Smith 
602840b8ebdSBarry Smith .keywords: coloring, Jacobian, finite differences
603840b8ebdSBarry Smith @*/
604840b8ebdSBarry Smith int MatFDColoringApplyTS(Mat J,MatFDColoring coloring,double t,Vec x1,MatStructure *flag,void *sctx)
605840b8ebdSBarry Smith {
606840b8ebdSBarry Smith   int           k,fg,ierr,N,start,end,l,row,col,srow;
607840b8ebdSBarry Smith   Scalar        dx, mone = -1.0,*y,*scale = coloring->scale,*xx,*wscale = coloring->wscale;
608840b8ebdSBarry Smith   double        epsilon = coloring->error_rel, umin = coloring->umin;
609840b8ebdSBarry Smith   MPI_Comm      comm = coloring->comm;
610840b8ebdSBarry Smith   Vec           w1,w2,w3;
611840b8ebdSBarry Smith   int           (*f)(void *,double,Vec,Vec,void *) = ( int (*)(void *,double,Vec,Vec,void *))coloring->f;
612840b8ebdSBarry Smith   void          *fctx = coloring->fctx;
613840b8ebdSBarry Smith 
6143a40ed3dSBarry Smith   PetscFunctionBegin;
615840b8ebdSBarry Smith   PetscValidHeaderSpecific(J,MAT_COOKIE);
616840b8ebdSBarry Smith   PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_COOKIE);
617840b8ebdSBarry Smith   PetscValidHeaderSpecific(x1,VEC_COOKIE);
618840b8ebdSBarry Smith 
619840b8ebdSBarry Smith   if (!coloring->w1) {
620840b8ebdSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1); CHKERRQ(ierr);
621840b8ebdSBarry Smith     PLogObjectParent(coloring,coloring->w1);
622840b8ebdSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2); CHKERRQ(ierr);
623840b8ebdSBarry Smith     PLogObjectParent(coloring,coloring->w2);
624840b8ebdSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3); CHKERRQ(ierr);
625840b8ebdSBarry Smith     PLogObjectParent(coloring,coloring->w3);
626840b8ebdSBarry Smith   }
627840b8ebdSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
628840b8ebdSBarry Smith 
629840b8ebdSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&fg); CHKERRQ(ierr);
630840b8ebdSBarry Smith   if (fg) {
631840b8ebdSBarry Smith     PLogInfo(coloring,"MatFDColoringApplyTS: Not calling MatZeroEntries()\n");
632840b8ebdSBarry Smith   } else {
633840b8ebdSBarry Smith     ierr = MatZeroEntries(J); CHKERRQ(ierr);
634840b8ebdSBarry Smith   }
635840b8ebdSBarry Smith 
636840b8ebdSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end); CHKERRQ(ierr);
637840b8ebdSBarry Smith   ierr = VecGetSize(x1,&N); CHKERRQ(ierr);
638840b8ebdSBarry Smith   ierr = (*f)(sctx,t,x1,w1,fctx); CHKERRQ(ierr);
639840b8ebdSBarry Smith 
640840b8ebdSBarry Smith   PetscMemzero(wscale,N*sizeof(Scalar));
641840b8ebdSBarry Smith   /*
642840b8ebdSBarry Smith       Loop over each color
643840b8ebdSBarry Smith   */
644840b8ebdSBarry Smith 
6453b28642cSBarry Smith   ierr = VecGetArray(x1,&xx); CHKERRQ(ierr);
646840b8ebdSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
647840b8ebdSBarry Smith     ierr = VecCopy(x1,w3); CHKERRQ(ierr);
648840b8ebdSBarry Smith     /*
649840b8ebdSBarry Smith        Loop over each column associated with color adding the
650840b8ebdSBarry Smith        perturbation to the vector w3.
651840b8ebdSBarry Smith     */
652840b8ebdSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
653840b8ebdSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
654840b8ebdSBarry Smith       dx  = xx[col-start];
655840b8ebdSBarry Smith       if (dx == 0.0) dx = 1.0;
6563a40ed3dSBarry Smith #if !defined(USE_PETSC_COMPLEX)
657840b8ebdSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
658840b8ebdSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
659840b8ebdSBarry Smith #else
660e20fef11SSatish Balay       if (PetscAbsScalar(dx) < umin && PetscReal(dx) >= 0.0)     dx = umin;
661e20fef11SSatish Balay       else if (PetscReal(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
662840b8ebdSBarry Smith #endif
663840b8ebdSBarry Smith       dx          *= epsilon;
664840b8ebdSBarry Smith       wscale[col] = 1.0/dx;
6653b28642cSBarry Smith       ierr = VecSetValues(w3,1,&col,&dx,ADD_VALUES); CHKERRQ(ierr);
666840b8ebdSBarry Smith     }
667840b8ebdSBarry Smith     /*
668840b8ebdSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
669840b8ebdSBarry Smith     */
670840b8ebdSBarry Smith     ierr = (*f)(sctx,t,w3,w2,fctx); CHKERRQ(ierr);
671840b8ebdSBarry Smith     ierr = VecAXPY(&mone,w1,w2); CHKERRQ(ierr);
672840b8ebdSBarry Smith     /* Communicate scale to all processors */
6733a40ed3dSBarry Smith #if !defined(USE_PETSC_COMPLEX)
674ca161407SBarry Smith     ierr = MPI_Allreduce(wscale,scale,N,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr);
675840b8ebdSBarry Smith #else
676ca161407SBarry Smith     ierr = MPI_Allreduce(wscale,scale,2*N,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr);
677840b8ebdSBarry Smith #endif
678840b8ebdSBarry Smith     /*
679840b8ebdSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
680840b8ebdSBarry Smith     */
6813b28642cSBarry Smith     ierr = VecGetArray(w2,&y); CHKERRQ(ierr);
682840b8ebdSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
683840b8ebdSBarry Smith       row    = coloring->rows[k][l];
684840b8ebdSBarry Smith       col    = coloring->columnsforrow[k][l];
685840b8ebdSBarry Smith       y[row] *= scale[col];
686840b8ebdSBarry Smith       srow   = row + start;
687840b8ebdSBarry Smith       ierr   = MatSetValues(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
688840b8ebdSBarry Smith     }
6893b28642cSBarry Smith     ierr = VecRestoreArray(w2,&y); CHKERRQ(ierr);
690840b8ebdSBarry Smith   }
6913b28642cSBarry Smith   ierr  = VecRestoreArray(x1,&xx); CHKERRQ(ierr);
692840b8ebdSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
693840b8ebdSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
6943a40ed3dSBarry Smith   PetscFunctionReturn(0);
695840b8ebdSBarry Smith }
6963b28642cSBarry Smith 
6973b28642cSBarry Smith 
6983b28642cSBarry Smith 
699