111320018SBarry Smith 211320018SBarry Smith #ifndef lint 3*edae2e7dSBarry Smith static char vcid[] = "$Id: snesj.c,v 1.3 1995/05/02 18:01:16 bsmith Exp bsmith $"; 411320018SBarry Smith #endif 511320018SBarry Smith 611320018SBarry Smith #include "draw.h" 711320018SBarry Smith #include "snesimpl.h" 811320018SBarry Smith #include "options.h" 911320018SBarry Smith 1011320018SBarry Smith /*@ 1123242f5aSBarry Smith SNESDefaultComputeJacobian - Computes Jacobian using finite 1223242f5aSBarry Smith differences. Slow and expensive. 1311320018SBarry Smith 1411320018SBarry Smith Input Parameters: 1523242f5aSBarry Smith . x - compute Jacobian at this point 1623242f5aSBarry Smith . ctx - applications Function context 1711320018SBarry Smith 1811320018SBarry Smith Output Parameters: 1923242f5aSBarry Smith . J - Jacobian 2023242f5aSBarry Smith . B - preconditioner, same as Jacobian 2111320018SBarry Smith 2223242f5aSBarry Smith .keywords: finite differences, Jacobian 2311320018SBarry Smith 2423242f5aSBarry Smith .seealso: SNESSetJacobian, SNESTestJacobian 2511320018SBarry Smith @*/ 2623242f5aSBarry Smith int SNESDefaultComputeJacobian(SNES snes, Vec x1,Mat *J,Mat *B,int *flag, 2723242f5aSBarry Smith void *ctx) 2811320018SBarry Smith { 2923242f5aSBarry Smith Vec j1,j2,x2; 3023242f5aSBarry Smith int i,ierr,N,start,end,j; 3123242f5aSBarry Smith Scalar dx, mone = -1.0,*y,scale; 3211320018SBarry Smith double norm; 3323242f5aSBarry Smith 3423242f5aSBarry Smith ierr = VecCreate(x1,&j1); CHKERR(ierr); 3523242f5aSBarry Smith ierr = VecCreate(x1,&j2); CHKERR(ierr); 3623242f5aSBarry Smith ierr = VecCreate(x1,&x2); CHKERR(ierr); 3723242f5aSBarry Smith ierr = VecNorm(x1,&norm); CHKERR(ierr); 3823242f5aSBarry Smith dx = 1.e-8*norm; /* assumes double precision */ 3923242f5aSBarry Smith scale = -1.0/dx; 4023242f5aSBarry Smith 4123242f5aSBarry Smith ierr = VecGetSize(x1,&N); CHKERR(ierr); 4223242f5aSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end); CHKERR(ierr); 4323242f5aSBarry Smith ierr = SNESComputeFunction(snes,x1,j1); CHKERR(ierr); 4423242f5aSBarry Smith for ( i=0; i<N; i++ ) { 4523242f5aSBarry Smith ierr = VecCopy(x1,x2); CHKERR(ierr); 4623242f5aSBarry Smith if ( i>= start && i<end) { 4723242f5aSBarry Smith VecSetValues(x2,1,&i,&dx,AddValues); 4811320018SBarry Smith } 4923242f5aSBarry Smith ierr = SNESComputeFunction(snes,x2,j2); CHKERR(ierr); 5023242f5aSBarry Smith ierr = VecAXPY(&mone,j1,j2); CHKERR(ierr); 5123242f5aSBarry Smith VecScale(&scale,j2); 5223242f5aSBarry Smith VecGetArray(j2,&y); 5323242f5aSBarry Smith for ( j=start; j<end; j++ ) { 5423242f5aSBarry Smith if (y[j-start]) { 55*edae2e7dSBarry Smith ierr = MatSetValues(*J,1,&j,1,&i,y+j-start,INSERTVALUES); CHKERR(ierr); 5623242f5aSBarry Smith } 5723242f5aSBarry Smith } 5823242f5aSBarry Smith VecRestoreArray(j2,&y); 5923242f5aSBarry Smith } 60ee50ffe9SBarry Smith MatAssemblyBegin(*J,FINAL_ASSEMBLY); 6123242f5aSBarry Smith VecDestroy(x2); VecDestroy(j1); VecDestroy(j2); 62ee50ffe9SBarry Smith MatAssemblyEnd(*J,FINAL_ASSEMBLY); 6311320018SBarry Smith return 0; 6411320018SBarry Smith } 6511320018SBarry Smith 6611320018SBarry Smith /*@ 6723242f5aSBarry Smith SNESTestJacobian - Tests whether a hand computed Jacobian 6823242f5aSBarry Smith matches one compute via finite differences 6911320018SBarry Smith 7011320018SBarry Smith Input Parameters: 7111320018SBarry Smith 7223242f5aSBarry Smith Output Parameters: 7323242f5aSBarry Smith 7411320018SBarry Smith @*/ 7523242f5aSBarry Smith int SNESTestJacobian(SNES snes) 7611320018SBarry Smith { 7711320018SBarry Smith 7823242f5aSBarry Smith /* compute both versions of Jacobian */ 7911320018SBarry Smith 8023242f5aSBarry Smith /* compare */ 8111320018SBarry Smith 8211320018SBarry Smith return 0; 8311320018SBarry Smith } 84