xref: /petsc/src/snes/interface/snesj2.c (revision b0ae01b72e86b9a61f98fb31b3fb5fd71e830b1a)
191627157SBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>    /*I  "petscsnes.h"  I*/
391627157SBarry Smith 
44a2ae208SSatish Balay #undef __FUNCT__
54a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultComputeJacobianColor"
691627157SBarry Smith /*@C
72d0c0e3bSBarry Smith     SNESDefaultComputeJacobianColor - Computes the Jacobian using
8b4fc646aSLois Curfman McInnes     finite differences and coloring to exploit matrix sparsity.
991627157SBarry Smith 
10fee21e36SBarry Smith     Collective on SNES
11fee21e36SBarry Smith 
12c7afd0dbSLois Curfman McInnes     Input Parameters:
13c7afd0dbSLois Curfman McInnes +   snes - nonlinear solver object
14c7afd0dbSLois Curfman McInnes .   x1 - location at which to evaluate Jacobian
15c7afd0dbSLois Curfman McInnes -   ctx - coloring context, where ctx must have type MatFDColoring,
16c7afd0dbSLois Curfman McInnes           as created via MatFDColoringCreate()
17c7afd0dbSLois Curfman McInnes 
18c7afd0dbSLois Curfman McInnes     Output Parameters:
19c7afd0dbSLois Curfman McInnes +   J - Jacobian matrix (not altered in this routine)
20c7afd0dbSLois Curfman McInnes .   B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
21c7afd0dbSLois Curfman McInnes -   flag - flag indicating whether the matrix sparsity structure has changed
22c7afd0dbSLois Curfman McInnes 
2336851e7fSLois Curfman McInnes     Level: intermediate
2436851e7fSLois Curfman McInnes 
25b0ae01b7SPeter Brune .notes: If ctx is not provided, this will try to get the coloring from the DM.  If the DM type
26b0ae01b7SPeter Brune         has no coloring routine, then it will try to get the coloring from the matrix.  This
27b0ae01b7SPeter Brune         requires that the matrix have nonzero entries precomputed, such as in
28b0ae01b7SPeter Brune         snes/examples/tutorials/ex45.c.
29b0ae01b7SPeter Brune 
30b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse
3191627157SBarry Smith 
32b4fc646aSLois Curfman McInnes .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESDefaultComputeJacobian()
33ab637aeaSJed Brown           MatFDColoringCreate(), MatFDColoringSetFunction()
34cb5b572fSBarry Smith 
3591627157SBarry Smith @*/
3695d750ceSBarry Smith 
377087cfbeSBarry Smith PetscErrorCode  SNESDefaultComputeJacobianColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
3891627157SBarry Smith {
39b0ae01b7SPeter Brune   MatFDColoring  color = (MatFDColoring)ctx;
40dfbe8321SBarry Smith   PetscErrorCode ierr;
41*4e269d77SPeter Brune   DM dm;
42*4e269d77SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
43*4e269d77SPeter Brune   Vec                         F;
44*4e269d77SPeter Brune   void                        *funcctx;
45*4e269d77SPeter Brune   ISColoring                  iscoloring;
46b0ae01b7SPeter Brune   PetscBool                   hascolor;
47dff777c9SBarry Smith 
483a40ed3dSBarry Smith   PetscFunctionBegin;
49b0ae01b7SPeter Brune   if (color) {
50b0ae01b7SPeter Brune     PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6);
51b0ae01b7SPeter Brune   } else {
52*4e269d77SPeter Brune     ierr = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject *)&color);CHKERRQ(ierr);
53b0ae01b7SPeter Brune   }
5492abec31SBarry Smith   *flag = SAME_NONZERO_PATTERN;
55*4e269d77SPeter Brune   ierr = SNESGetFunction(snes,&F,&func,&funcctx);
56*4e269d77SPeter Brune   if (!color) {
57*4e269d77SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
58b0ae01b7SPeter Brune     ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr);
59b0ae01b7SPeter Brune     if (hascolor) {
60*4e269d77SPeter Brune       ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr);
61*4e269d77SPeter Brune       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
62*4e269d77SPeter Brune       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
63*4e269d77SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
64*4e269d77SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
65b0ae01b7SPeter Brune     } else {
66b0ae01b7SPeter Brune       ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
67b0ae01b7SPeter Brune       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
68b0ae01b7SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr);
69b0ae01b7SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
70b0ae01b7SPeter Brune     }
71*4e269d77SPeter Brune     ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr);
724a9d489dSBarry Smith   }
73*4e269d77SPeter Brune   ierr  = MatFDColoringSetF(color,PETSC_NULL);CHKERRQ(ierr);
74005c665bSBarry Smith   ierr  = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr);
7532dfb669SBarry Smith   if (*J != *B) {
76194405b3SBarry Smith     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
77194405b3SBarry Smith     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
78194405b3SBarry Smith   }
793a40ed3dSBarry Smith   PetscFunctionReturn(0);
8091627157SBarry Smith }
81