xref: /petsc/src/snes/interface/snesj2.c (revision 1e25c2744a56dc779d05d2a7975a7f2272f1aa7b)
191627157SBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>    /*I  "petscsnes.h"  I*/
3*1e25c274SJed Brown #include <petscdm.h>                   /*I  "petscdm.h"    I*/
491627157SBarry Smith 
54a2ae208SSatish Balay #undef __FUNCT__
64a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultComputeJacobianColor"
791627157SBarry Smith /*@C
82d0c0e3bSBarry Smith     SNESDefaultComputeJacobianColor - Computes the Jacobian using
9b4fc646aSLois Curfman McInnes     finite differences and coloring to exploit matrix sparsity.
1091627157SBarry Smith 
11fee21e36SBarry Smith     Collective on SNES
12fee21e36SBarry Smith 
13c7afd0dbSLois Curfman McInnes     Input Parameters:
14c7afd0dbSLois Curfman McInnes +   snes - nonlinear solver object
15c7afd0dbSLois Curfman McInnes .   x1 - location at which to evaluate Jacobian
16243e2ce7SPeter Brune -   ctx - ignored context parameter
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 
25243e2ce7SPeter Brune .notes: This will first 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 {
390298fd71SBarry Smith   MatFDColoring  color = NULL;
40dfbe8321SBarry Smith   PetscErrorCode ierr;
414e269d77SPeter Brune   DM             dm;
424e269d77SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
434e269d77SPeter Brune   Vec            F;
444e269d77SPeter Brune   void           *funcctx;
454e269d77SPeter Brune   ISColoring     iscoloring;
46b0ae01b7SPeter Brune   PetscBool      hascolor;
47dff777c9SBarry Smith 
483a40ed3dSBarry Smith   PetscFunctionBegin;
494e269d77SPeter Brune   ierr  = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);
5092abec31SBarry Smith   *flag = SAME_NONZERO_PATTERN;
5122d28d08SBarry Smith   ierr  = SNESGetFunction(snes,&F,&func,&funcctx);CHKERRQ(ierr);
524e269d77SPeter Brune   if (!color) {
534e269d77SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
54b0ae01b7SPeter Brune     ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr);
55b0ae01b7SPeter Brune     if (hascolor) {
564e269d77SPeter Brune       ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr);
574e269d77SPeter Brune       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
584e269d77SPeter Brune       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
594e269d77SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
604e269d77SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
61b0ae01b7SPeter Brune     } else {
62b0ae01b7SPeter Brune       ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
63b0ae01b7SPeter Brune       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
640171d955SPeter Brune       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
65b0ae01b7SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr);
66b0ae01b7SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
67b0ae01b7SPeter Brune     }
684e269d77SPeter Brune     ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr);
694108615fSPeter Brune     ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr);
704a9d489dSBarry Smith   }
7195862db2SPeter Brune 
7295862db2SPeter Brune   /* F is only usable if there is no RHS on the SNES */
7395862db2SPeter Brune   if (!snes->vec_rhs) {
74432bb422SPeter Brune     ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr);
7595862db2SPeter Brune   }
76005c665bSBarry Smith   ierr = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr);
7732dfb669SBarry Smith   if (*J != *B) {
78194405b3SBarry Smith     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
79194405b3SBarry Smith     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
80194405b3SBarry Smith   }
813a40ed3dSBarry Smith   PetscFunctionReturn(0);
8291627157SBarry Smith }
83