xref: /petsc/src/snes/interface/snesj2.c (revision 7fb4102547d56360221aeb08cedee185f3d105e5)
191627157SBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>    /*I  "petscsnes.h"  I*/
31e25c274SJed Brown #include <petscdm.h>                   /*I  "petscdm.h"    I*/
491627157SBarry Smith 
54a2ae208SSatish Balay #undef __FUNCT__
68d359177SBarry Smith #define __FUNCT__ "SNESComputeJacobianDefaultColor"
791627157SBarry Smith /*@C
88d359177SBarry Smith     SNESComputeJacobianDefaultColor - 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
16*7fb41025SPeter Brune -   ctx - MatFDColoring context or NULL
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 
25*7fb41025SPeter Brune .notes: If the coloring is not provided through the context, this will first try to get the
26*7fb41025SPeter Brune         coloring from the DM.  If the DM type has no coloring routine, then it will try to
27*7fb41025SPeter Brune         get the coloring from the matrix.  This requires that the matrix have nonzero entries
28*7fb41025SPeter Brune         precomputed.  This is discouraged, as MatGetColoring() is not parallel.
29b0ae01b7SPeter Brune 
30b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse
3191627157SBarry Smith 
328d359177SBarry Smith .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault()
33ab637aeaSJed Brown           MatFDColoringCreate(), MatFDColoringSetFunction()
34cb5b572fSBarry Smith 
3591627157SBarry Smith @*/
3695d750ceSBarry Smith 
378d359177SBarry Smith PetscErrorCode  SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
3891627157SBarry Smith {
39*7fb41025SPeter Brune   MatFDColoring  color = (MatFDColoring)ctx;
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;
49*7fb41025SPeter Brune   if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6);
50*7fb41025SPeter Brune   else {ierr  = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);}
5192abec31SBarry Smith   *flag = SAME_NONZERO_PATTERN;
5222d28d08SBarry Smith   ierr  = SNESGetFunction(snes,&F,&func,&funcctx);CHKERRQ(ierr);
534e269d77SPeter Brune   if (!color) {
544e269d77SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
55b0ae01b7SPeter Brune     ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr);
56b0ae01b7SPeter Brune     if (hascolor) {
574e269d77SPeter Brune       ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr);
584e269d77SPeter Brune       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
594e269d77SPeter Brune       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
604e269d77SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
614e269d77SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
62b0ae01b7SPeter Brune     } else {
63b0ae01b7SPeter Brune       ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
64b0ae01b7SPeter Brune       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
650171d955SPeter Brune       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
66b0ae01b7SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr);
67b0ae01b7SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
68b0ae01b7SPeter Brune     }
694e269d77SPeter Brune     ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr);
704108615fSPeter Brune     ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr);
714a9d489dSBarry Smith   }
7295862db2SPeter Brune 
7395862db2SPeter Brune   /* F is only usable if there is no RHS on the SNES */
7495862db2SPeter Brune   if (!snes->vec_rhs) {
75432bb422SPeter Brune     ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr);
7695862db2SPeter Brune   }
77005c665bSBarry Smith   ierr = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr);
7832dfb669SBarry Smith   if (*J != *B) {
79194405b3SBarry Smith     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
80194405b3SBarry Smith     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
81194405b3SBarry Smith   }
823a40ed3dSBarry Smith   PetscFunctionReturn(0);
8391627157SBarry Smith }
84