xref: /petsc/src/mat/matfd/fdmatrix.c (revision 639f9d9dbbc54d6ac4e42e98283c540b41bb2cee)
1bbf0e169SBarry Smith 
2bbf0e169SBarry Smith #ifndef lint
3*639f9d9dSBarry Smith static char vcid[] = "$Id: fdmatrix.c,v 1.1 1996/10/09 17:52:05 bsmith Exp bsmith $";
4bbf0e169SBarry Smith #endif
5bbf0e169SBarry Smith 
6bbf0e169SBarry Smith /*
7*639f9d9dSBarry Smith    This is where the abstract matrix operations are defined that are
8*639f9d9dSBarry 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 #include "pinclude/pviewer.h"
15bbf0e169SBarry Smith 
16bbf0e169SBarry Smith /*@C
17*639f9d9dSBarry Smith    MatFDColoringView - Views a finite difference coloring context.
18bbf0e169SBarry Smith 
19*639f9d9dSBarry Smith    Input  Parameter:
20*639f9d9dSBarry Smith .   color - the coloring context
21bbf0e169SBarry Smith 
22bbf0e169SBarry Smith 
23*639f9d9dSBarry Smith .seealso: MatFDColoringCreate()
24bbf0e169SBarry Smith @*/
25*639f9d9dSBarry Smith int MatFDColoringView(MatFDColoring color,Viewer viewer)
26bbf0e169SBarry Smith {
27*639f9d9dSBarry Smith   int i,j,format,ierr;
28bbf0e169SBarry Smith 
29*639f9d9dSBarry Smith   if (!viewer) viewer = VIEWER_STDOUT_WORLD;
30bbf0e169SBarry Smith 
31bbf0e169SBarry Smith   ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr);
32*639f9d9dSBarry Smith 
33*639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO) {
34*639f9d9dSBarry Smith     printf("MatFDColoring Object:\n");
35*639f9d9dSBarry Smith     printf("  Error tolerance %g\n",color->error_rel);
36*639f9d9dSBarry Smith     printf("  umin %g\n",color->umin);
37*639f9d9dSBarry Smith   } else {
38*639f9d9dSBarry Smith     printf("MatFDColoring Object:\n");
39*639f9d9dSBarry Smith     printf("  Error tolerance %g\n",color->error_rel);
40*639f9d9dSBarry Smith     printf("  umin %g\n",color->umin);
41*639f9d9dSBarry Smith     printf("Number of colors %d\n",color->ncolors);
42*639f9d9dSBarry Smith     for ( i=0; i<color->ncolors; i++ ) {
43*639f9d9dSBarry Smith       printf("Information for color %d\n",i);
44*639f9d9dSBarry Smith       printf("Number of columns %d\n",color->ncolumns[i]);
45*639f9d9dSBarry Smith       for ( j=0; j<color->ncolumns[i]; j++ ) {
46*639f9d9dSBarry Smith         printf("  %d\n",color->columns[i][j]);
47*639f9d9dSBarry Smith       }
48*639f9d9dSBarry Smith       printf("Number of rows %d\n",color->nrows[i]);
49*639f9d9dSBarry Smith       for ( j=0; j<color->nrows[i]; j++ ) {
50*639f9d9dSBarry Smith         printf("  %d %d \n",color->rows[i][j],color->columnsforrow[i][j]);
51bbf0e169SBarry Smith       }
52bbf0e169SBarry Smith     }
53bbf0e169SBarry Smith   }
54*639f9d9dSBarry Smith   return 0;
55*639f9d9dSBarry Smith }
56*639f9d9dSBarry Smith 
57*639f9d9dSBarry Smith /*@
58*639f9d9dSBarry Smith    MatFDColoringSetParameters - Sets the parameters for the approximation of
59*639f9d9dSBarry Smith    Jacobian using finite differences.
60*639f9d9dSBarry Smith 
61*639f9d9dSBarry Smith $       J(u)_{:,i} = [J(u+h*dx_{i}) - J(u)]/h where
62*639f9d9dSBarry Smith $        h = error_rel*u[i]                    if  u[i] > umin
63*639f9d9dSBarry Smith $          = error_rel*umin                    else
64*639f9d9dSBarry Smith $
65*639f9d9dSBarry Smith $   dx_{i} = (0, ... 1, .... 0)
66*639f9d9dSBarry Smith 
67*639f9d9dSBarry Smith    Input Parameters:
68*639f9d9dSBarry Smith .  coloring - the jacobian coloring context
69*639f9d9dSBarry Smith .  error_rel - relative error
70*639f9d9dSBarry Smith .  umin - minimum allowable u-value
71*639f9d9dSBarry Smith 
72*639f9d9dSBarry Smith .keywords: SNES, Jacobian, finite differences, parameters
73*639f9d9dSBarry Smith @*/
74*639f9d9dSBarry Smith int MatFDColoringSetParameters(MatFDColoring matfd,double error,double umin)
75*639f9d9dSBarry Smith {
76*639f9d9dSBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE);
77*639f9d9dSBarry Smith 
78*639f9d9dSBarry Smith   if (error != PETSC_DEFAULT) matfd->error_rel = error;
79*639f9d9dSBarry Smith   if (umin != PETSC_DEFAULT)  matfd->umin      = umin;
80*639f9d9dSBarry Smith   return 0;
81*639f9d9dSBarry Smith }
82*639f9d9dSBarry Smith 
83*639f9d9dSBarry Smith /*@
84*639f9d9dSBarry Smith    MatFDColoringSetFromOptions - Set coloring finite difference parameters from
85*639f9d9dSBarry Smith          the options database.
86*639f9d9dSBarry Smith 
87*639f9d9dSBarry Smith $       J(u)_{:,i} = [J(u+h*dx_{i}) - J(u)]/h where
88*639f9d9dSBarry Smith $        h = error_rel*u[i]                    if  u[i] > umin
89*639f9d9dSBarry Smith $          = error_rel*.1                      else
90*639f9d9dSBarry Smith $
91*639f9d9dSBarry Smith $   dx_{i} = (0, ... 1, .... 0)
92*639f9d9dSBarry Smith 
93*639f9d9dSBarry Smith    Input Parameters:
94*639f9d9dSBarry Smith .  coloring - the jacobian coloring context
95*639f9d9dSBarry Smith 
96*639f9d9dSBarry Smith    Options Database:
97*639f9d9dSBarry Smith .  -mat_fd_coloring_error square root of relative error in function
98*639f9d9dSBarry Smith .  -mat_fd_coloring_umin  see above
99*639f9d9dSBarry Smith 
100*639f9d9dSBarry Smith .keywords: SNES, Jacobian, finite differences, parameters
101*639f9d9dSBarry Smith @*/
102*639f9d9dSBarry Smith int MatFDColoringSetFromOptions(MatFDColoring matfd)
103*639f9d9dSBarry Smith {
104*639f9d9dSBarry Smith   int    ierr,flag;
105*639f9d9dSBarry Smith   double error = PETSC_DEFAULT,umin = PETSC_DEFAULT;
106*639f9d9dSBarry Smith   PetscValidHeaderSpecific(matfd,MAT_FDCOLORING_COOKIE);
107*639f9d9dSBarry Smith 
108*639f9d9dSBarry Smith   ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_err",&error,&flag);CHKERRQ(ierr);
109*639f9d9dSBarry Smith   ierr = OptionsGetDouble(matfd->prefix,"-mat_fd_coloring_umin",&umin,&flag);CHKERRQ(ierr);
110*639f9d9dSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help",&flag); CHKERRQ(ierr);
111*639f9d9dSBarry Smith   ierr = MatFDColoringSetParameters(matfd,error,umin); CHKERRQ(ierr);
112*639f9d9dSBarry Smith   if (flag) {
113*639f9d9dSBarry Smith     ierr = MatFDColoringPrintHelp(matfd); CHKERRQ(ierr);
114*639f9d9dSBarry Smith   }
115*639f9d9dSBarry Smith   return 0;
116*639f9d9dSBarry Smith }
117*639f9d9dSBarry Smith 
118*639f9d9dSBarry Smith /*@
119*639f9d9dSBarry Smith     MatFDColoringPrintHelp - Prints help message for matrix finite difference calculations
120*639f9d9dSBarry Smith          using coloring.
121*639f9d9dSBarry Smith 
122*639f9d9dSBarry Smith    Input Parameter:
123*639f9d9dSBarry Smith .   fdcoloring - the MatFDColoring context
124*639f9d9dSBarry Smith 
125*639f9d9dSBarry Smith .seealso: MatFDColoringCreate(), MatFDColoringDestroy(), MatFDColoringSetFromOptions()
126*639f9d9dSBarry Smith @*/
127*639f9d9dSBarry Smith int MatFDColoringPrintHelp(MatFDColoring fd)
128*639f9d9dSBarry Smith {
129*639f9d9dSBarry Smith   PetscValidHeaderSpecific(fd,MAT_FDCOLORING_COOKIE);
130*639f9d9dSBarry Smith 
131*639f9d9dSBarry Smith   PetscPrintf(fd->comm,"-mat_fd_coloring_err <err> set sqrt rel tol in function. Default 1.e-8\n");
132*639f9d9dSBarry Smith   PetscPrintf(fd->comm,"-mat_fd_coloring_umin <umin> see users manual. Default 1.e-8\n");
133bbf0e169SBarry Smith   return 0;
134bbf0e169SBarry Smith }
135bbf0e169SBarry Smith 
136bbf0e169SBarry Smith /*@C
137*639f9d9dSBarry Smith    MatFDColoringCreate - Creates a matrix coloring context for finite difference
138*639f9d9dSBarry Smith         computation of Jacobians.
139bbf0e169SBarry Smith 
140*639f9d9dSBarry Smith    Input Parameters:
141*639f9d9dSBarry Smith .    mat - the matrix containing the nonzero structure of the Jacobian
142*639f9d9dSBarry Smith .    iscoloring - the coloring of the matrix
143bbf0e169SBarry Smith 
144bbf0e169SBarry Smith    Output Parameter:
145*639f9d9dSBarry Smith .   color - the new coloring context
146bbf0e169SBarry Smith 
147*639f9d9dSBarry Smith 
148*639f9d9dSBarry Smith .seealso: MatFDColoringDestroy()
149bbf0e169SBarry Smith @*/
150*639f9d9dSBarry Smith int MatFDColoringCreate(Mat mat,ISColoring iscoloring,MatFDColoring *color)
151bbf0e169SBarry Smith {
152*639f9d9dSBarry Smith   MatFDColoring c;
153*639f9d9dSBarry Smith   MPI_Comm      comm;
154*639f9d9dSBarry Smith   int           ierr,M,N;
155*639f9d9dSBarry Smith 
156*639f9d9dSBarry Smith   ierr = MatGetSize(mat,&M,&N); CHKERRQ(ierr);
157*639f9d9dSBarry Smith   if (M != N) SETERRQ(1,"MatFDColoringCreate:Only for square matrices");
158*639f9d9dSBarry Smith 
159*639f9d9dSBarry Smith   PetscObjectGetComm((PetscObject)mat,&comm);
160*639f9d9dSBarry Smith   PetscHeaderCreate(c,_MatFDColoring,MAT_FDCOLORING_COOKIE,0,comm);
161*639f9d9dSBarry Smith   PLogObjectCreate(c);
162*639f9d9dSBarry Smith 
163*639f9d9dSBarry Smith   if (mat->ops.fdcoloringcreate) {
164*639f9d9dSBarry Smith     ierr = (*mat->ops.fdcoloringcreate)(mat,iscoloring,c); CHKERRQ(ierr);
165*639f9d9dSBarry Smith   } else {
166*639f9d9dSBarry Smith     SETERRQ(1,"MatFDColoringCreate:Code not yet written for this matrix type");
167*639f9d9dSBarry Smith   }
168*639f9d9dSBarry Smith 
169*639f9d9dSBarry Smith   c->error_rel = 1.e-8;
170*639f9d9dSBarry Smith   c->umin      = 1.e-5;
171*639f9d9dSBarry Smith 
172*639f9d9dSBarry Smith   *color = c;
173*639f9d9dSBarry Smith 
174bbf0e169SBarry Smith   return 0;
175bbf0e169SBarry Smith }
176bbf0e169SBarry Smith 
177bbf0e169SBarry Smith /*@C
178*639f9d9dSBarry Smith     MatFDColoringDestroy - Destroys a matrix coloring context that was created
179*639f9d9dSBarry Smith          via MatFDColoringCreate().
180bbf0e169SBarry Smith 
181*639f9d9dSBarry Smith     Input Paramter:
182*639f9d9dSBarry Smith .   c - coloring context
183bbf0e169SBarry Smith 
184*639f9d9dSBarry Smith .seealso: MatFDColoringCreate()
185bbf0e169SBarry Smith @*/
186*639f9d9dSBarry Smith int MatFDColoringDestroy(MatFDColoring c)
187bbf0e169SBarry Smith {
188*639f9d9dSBarry Smith   int i,ierr,flag;
189bbf0e169SBarry Smith 
190*639f9d9dSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-matfdcoloring_view",&flag);
191*639f9d9dSBarry Smith   if (flag) {
192bbf0e169SBarry Smith     Viewer viewer;
193*639f9d9dSBarry Smith     ierr = ViewerFileOpenASCII(c->comm,"stdout",&viewer);CHKERRQ(ierr);
194*639f9d9dSBarry Smith     ierr = MatFDColoringView(c,viewer);CHKERRQ(ierr);
195bbf0e169SBarry Smith     ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
196bbf0e169SBarry Smith   }
197*639f9d9dSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-matfdcoloring_view_info",&flag);
198*639f9d9dSBarry Smith   if (flag) {
199bbf0e169SBarry Smith     Viewer viewer;
200*639f9d9dSBarry Smith     ierr = ViewerFileOpenASCII(c->comm,"stdout",&viewer);CHKERRQ(ierr);
201*639f9d9dSBarry Smith     ierr = ViewerPushFormat(viewer,VIEWER_FORMAT_ASCII_INFO, PETSC_NULL); CHKERRQ(ierr);
202*639f9d9dSBarry Smith     ierr = MatFDColoringView(c,viewer);CHKERRQ(ierr);
203*639f9d9dSBarry Smith     ierr = ViewerPopFormat(viewer);
204bbf0e169SBarry Smith     ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
205bbf0e169SBarry Smith   }
206*639f9d9dSBarry Smith 
207*639f9d9dSBarry Smith   for ( i=0; i<c->ncolors; i++ ) {
208*639f9d9dSBarry Smith     if (c->columns[i])       PetscFree(c->columns[i]);
209*639f9d9dSBarry Smith     if (c->rows[i])          PetscFree(c->rows[i]);
210*639f9d9dSBarry Smith     if (c->columnsforrow[i]) PetscFree(c->columnsforrow[i]);
211bbf0e169SBarry Smith   }
212*639f9d9dSBarry Smith   PetscFree(c->ncolumns);
213*639f9d9dSBarry Smith   PetscFree(c->columns);
214*639f9d9dSBarry Smith   PetscFree(c->nrows);
215*639f9d9dSBarry Smith   PetscFree(c->rows);
216*639f9d9dSBarry Smith   PetscFree(c->columnsforrow);
217*639f9d9dSBarry Smith   PetscFree(c->scale);
218*639f9d9dSBarry Smith   PLogObjectDestroy(c);
219*639f9d9dSBarry Smith   PetscHeaderDestroy(c);
220bbf0e169SBarry Smith   return 0;
221bbf0e169SBarry Smith }
222