xref: /petsc/src/snes/interface/snesj2.c (revision f80563f664061ecd967ef1059d09729755f4809c)
191627157SBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>    /*I  "petscsnes.h"  I*/
31e25c274SJed Brown #include <petscdm.h>                   /*I  "petscdm.h"    I*/
491627157SBarry Smith 
562cd874fSBarry Smith /*
662cd874fSBarry Smith    MatFDColoringSetFunction() takes a function with four arguments, we want to use SNESComputeFunction()
762cd874fSBarry Smith    since it logs function computation information.
862cd874fSBarry Smith */
962cd874fSBarry Smith static PetscErrorCode SNESComputeFunctionCtx(SNES snes,Vec x,Vec f,void *ctx)
1062cd874fSBarry Smith {
1162cd874fSBarry Smith   return SNESComputeFunction(snes,x,f);
1262cd874fSBarry Smith }
1362cd874fSBarry Smith 
1491627157SBarry Smith /*@C
158d359177SBarry Smith     SNESComputeJacobianDefaultColor - Computes the Jacobian using
16b4fc646aSLois Curfman McInnes     finite differences and coloring to exploit matrix sparsity.
1791627157SBarry Smith 
18fee21e36SBarry Smith     Collective on SNES
19fee21e36SBarry Smith 
20c7afd0dbSLois Curfman McInnes     Input Parameters:
21c7afd0dbSLois Curfman McInnes +   snes - nonlinear solver object
22c7afd0dbSLois Curfman McInnes .   x1 - location at which to evaluate Jacobian
237fb41025SPeter Brune -   ctx - MatFDColoring context or NULL
24c7afd0dbSLois Curfman McInnes 
25c7afd0dbSLois Curfman McInnes     Output Parameters:
26c7afd0dbSLois Curfman McInnes +   J - Jacobian matrix (not altered in this routine)
2756744491SBarry Smith -   B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
28c7afd0dbSLois Curfman McInnes 
2936851e7fSLois Curfman McInnes     Level: intermediate
3036851e7fSLois Curfman McInnes 
315620d6dcSBarry Smith    Options Database Key:
325620d6dcSBarry Smith +  -snes_fd_color_use_mat - use a matrix coloring from the explicit matrix nonzero pattern instead of from the DM providing the matrix
335620d6dcSBarry Smith .  -snes_fd_color - Activates SNESComputeJacobianDefaultColor() in SNESSetFromOptions()
345620d6dcSBarry Smith .  -mat_fd_coloring_err <err> - Sets <err> (square root of relative error in the function)
355620d6dcSBarry Smith .  -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude
365620d6dcSBarry Smith -  -mat_fd_type - Either wp or ds (see MATMFFD_WP or MATMFFD_DS)
375620d6dcSBarry Smith 
385620d6dcSBarry Smith     Notes: If the coloring is not provided through the context, this will first try to get the
397fb41025SPeter Brune         coloring from the DM.  If the DM type has no coloring routine, then it will try to
407fb41025SPeter Brune         get the coloring from the matrix.  This requires that the matrix have nonzero entries
41*f80563f6SBarry Smith         precomputed.
42b0ae01b7SPeter Brune 
43b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse
4491627157SBarry Smith 
458d359177SBarry Smith .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault()
46ab637aeaSJed Brown           MatFDColoringCreate(), MatFDColoringSetFunction()
47cb5b572fSBarry Smith 
4891627157SBarry Smith @*/
4995d750ceSBarry Smith 
50d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
5191627157SBarry Smith {
527fb41025SPeter Brune   MatFDColoring  color = (MatFDColoring)ctx;
53dfbe8321SBarry Smith   PetscErrorCode ierr;
544e269d77SPeter Brune   DM             dm;
55335efc43SPeter Brune   MatColoring    mc;
564e269d77SPeter Brune   ISColoring     iscoloring;
57b0ae01b7SPeter Brune   PetscBool      hascolor;
58aa2f1b4eSJed Brown   PetscBool      solvec,matcolor = PETSC_FALSE;
59dff777c9SBarry Smith 
603a40ed3dSBarry Smith   PetscFunctionBegin;
617fb41025SPeter Brune   if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6);
6294ab13aaSBarry Smith   else {ierr  = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);}
6362cd874fSBarry Smith 
644e269d77SPeter Brune   if (!color) {
654e269d77SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
66b0ae01b7SPeter Brune     ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr);
67924833adSPeter Brune     matcolor = PETSC_FALSE;
68c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr);
69c3138ed3SPeter Brune     if (hascolor && !matcolor) {
70b412c318SBarry Smith       ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr);
7194ab13aaSBarry Smith       ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr);
7262cd874fSBarry Smith       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr);
734e269d77SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7494ab13aaSBarry Smith       ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr);
75f86b9fbaSHong Zhang       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
76b0ae01b7SPeter Brune     } else {
7794ab13aaSBarry Smith       ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr);
78335efc43SPeter Brune       ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr);
79335efc43SPeter Brune       ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr);
80335efc43SPeter Brune       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
81335efc43SPeter Brune       ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr);
82335efc43SPeter Brune       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
8394ab13aaSBarry Smith       ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr);
8462cd874fSBarry Smith       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr);
85b0ae01b7SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
8694ab13aaSBarry Smith       ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr);
87f86b9fbaSHong Zhang       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
88b0ae01b7SPeter Brune     }
8994ab13aaSBarry Smith     ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr);
904108615fSPeter Brune     ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr);
914a9d489dSBarry Smith   }
9295862db2SPeter Brune 
93c89319d2SPeter Brune   /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */
94c89319d2SPeter Brune   ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr);
95c89319d2SPeter Brune   if (!snes->vec_rhs && solvec) {
9662cd874fSBarry Smith     Vec F;
9762cd874fSBarry Smith     ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr);
98432bb422SPeter Brune     ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr);
9995862db2SPeter Brune   }
100d1e9a80fSBarry Smith   ierr = MatFDColoringApply(B,color,x1,snes);CHKERRQ(ierr);
10194ab13aaSBarry Smith   if (J != B) {
10294ab13aaSBarry Smith     ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10394ab13aaSBarry Smith     ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
104194405b3SBarry Smith   }
1053a40ed3dSBarry Smith   PetscFunctionReturn(0);
10691627157SBarry Smith }
107