xref: /petsc/src/snes/interface/snesj2.c (revision 432bb422eb921a2bb0b7862b58d8db880ee7941e)
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
15243e2ce7SPeter Brune -   ctx - ignored context parameter
16c7afd0dbSLois Curfman McInnes 
17c7afd0dbSLois Curfman McInnes     Output Parameters:
18c7afd0dbSLois Curfman McInnes +   J - Jacobian matrix (not altered in this routine)
19c7afd0dbSLois Curfman McInnes .   B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
20c7afd0dbSLois Curfman McInnes -   flag - flag indicating whether the matrix sparsity structure has changed
21c7afd0dbSLois Curfman McInnes 
2236851e7fSLois Curfman McInnes     Level: intermediate
2336851e7fSLois Curfman McInnes 
24243e2ce7SPeter Brune .notes: This will first try to get the coloring from the DM.  If the DM type
25b0ae01b7SPeter Brune         has no coloring routine, then it will try to get the coloring from the matrix.  This
26b0ae01b7SPeter Brune         requires that the matrix have nonzero entries precomputed, such as in
27b0ae01b7SPeter Brune         snes/examples/tutorials/ex45.c.
28b0ae01b7SPeter Brune 
29b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse
3091627157SBarry Smith 
31b4fc646aSLois Curfman McInnes .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESDefaultComputeJacobian()
32ab637aeaSJed Brown           MatFDColoringCreate(), MatFDColoringSetFunction()
33cb5b572fSBarry Smith 
3491627157SBarry Smith @*/
3595d750ceSBarry Smith 
367087cfbeSBarry Smith PetscErrorCode  SNESDefaultComputeJacobianColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
3791627157SBarry Smith {
38243e2ce7SPeter Brune   MatFDColoring  color = PETSC_NULL;
39dfbe8321SBarry Smith   PetscErrorCode ierr;
404e269d77SPeter Brune   DM dm;
414e269d77SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
424e269d77SPeter Brune   Vec                         F;
434e269d77SPeter Brune   void                        *funcctx;
444e269d77SPeter Brune   ISColoring                  iscoloring;
45b0ae01b7SPeter Brune   PetscBool                   hascolor;
46dff777c9SBarry Smith 
473a40ed3dSBarry Smith   PetscFunctionBegin;
484e269d77SPeter Brune   ierr = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject *)&color);CHKERRQ(ierr);
4992abec31SBarry Smith   *flag = SAME_NONZERO_PATTERN;
504e269d77SPeter Brune   ierr = SNESGetFunction(snes,&F,&func,&funcctx);
514e269d77SPeter Brune   if (!color) {
524e269d77SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
53b0ae01b7SPeter Brune     ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr);
54b0ae01b7SPeter Brune     if (hascolor) {
554e269d77SPeter Brune       ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr);
564e269d77SPeter Brune       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
574e269d77SPeter Brune       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
584e269d77SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
594e269d77SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
60b0ae01b7SPeter Brune     } else {
61b0ae01b7SPeter Brune       ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
62b0ae01b7SPeter Brune       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
630171d955SPeter Brune       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
64b0ae01b7SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr);
65b0ae01b7SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
66b0ae01b7SPeter Brune     }
674e269d77SPeter Brune     ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr);
684108615fSPeter Brune     ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr);
694a9d489dSBarry Smith   }
70*432bb422SPeter Brune   ierr  = MatFDColoringSetF(color,F);CHKERRQ(ierr);
71005c665bSBarry Smith   ierr  = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr);
7232dfb669SBarry Smith   if (*J != *B) {
73194405b3SBarry Smith     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
74194405b3SBarry Smith     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
75194405b3SBarry Smith   }
763a40ed3dSBarry Smith   PetscFunctionReturn(0);
7791627157SBarry Smith }
78