xref: /petsc/src/snes/interface/snesj2.c (revision 94ab13aa5a241d09deaff0170a61a1239553c040)
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
167fb41025SPeter 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 
257fb41025SPeter Brune .notes: If the coloring is not provided through the context, this will first try to get the
267fb41025SPeter Brune         coloring from the DM.  If the DM type has no coloring routine, then it will try to
277fb41025SPeter Brune         get the coloring from the matrix.  This requires that the matrix have nonzero entries
287086a01eSPeter Brune         precomputed.  This is discouraged, as MatColoringApply() is not parallel by default.
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 
37*94ab13aaSBarry Smith PetscErrorCode  SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,MatStructure *flag,void *ctx)
3891627157SBarry Smith {
397fb41025SPeter 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;
45335efc43SPeter Brune   MatColoring    mc;
464e269d77SPeter Brune   ISColoring     iscoloring;
47b0ae01b7SPeter Brune   PetscBool      hascolor;
48aa2f1b4eSJed Brown   PetscBool      solvec,matcolor = PETSC_FALSE;
49dff777c9SBarry Smith 
503a40ed3dSBarry Smith   PetscFunctionBegin;
517fb41025SPeter Brune   if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6);
52*94ab13aaSBarry Smith   else {ierr  = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);}
5392abec31SBarry Smith   *flag = SAME_NONZERO_PATTERN;
5422d28d08SBarry Smith   ierr  = SNESGetFunction(snes,&F,&func,&funcctx);CHKERRQ(ierr);
554e269d77SPeter Brune   if (!color) {
564e269d77SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
57b0ae01b7SPeter Brune     ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr);
58924833adSPeter Brune     matcolor = PETSC_FALSE;
59c3138ed3SPeter Brune     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr);
60c3138ed3SPeter Brune     if (hascolor && !matcolor) {
61b412c318SBarry Smith       ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr);
62*94ab13aaSBarry Smith       ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr);
634e269d77SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
644e269d77SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
65*94ab13aaSBarry Smith       ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr);
66f86b9fbaSHong Zhang       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
67b0ae01b7SPeter Brune     } else {
68*94ab13aaSBarry Smith       ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr);
69335efc43SPeter Brune       ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr);
70335efc43SPeter Brune       ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr);
71335efc43SPeter Brune       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
72335efc43SPeter Brune       ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr);
73335efc43SPeter Brune       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
74*94ab13aaSBarry Smith       ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr);
75b0ae01b7SPeter Brune       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr);
76b0ae01b7SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
77*94ab13aaSBarry Smith       ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr);
78f86b9fbaSHong Zhang       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
79b0ae01b7SPeter Brune     }
80*94ab13aaSBarry Smith     ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr);
814108615fSPeter Brune     ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr);
824a9d489dSBarry Smith   }
8395862db2SPeter Brune 
84c89319d2SPeter Brune   /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */
85c89319d2SPeter Brune   ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr);
86c89319d2SPeter Brune   if (!snes->vec_rhs && solvec) {
87432bb422SPeter Brune     ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr);
8895862db2SPeter Brune   }
89*94ab13aaSBarry Smith   ierr = MatFDColoringApply(B,color,x1,flag,snes);CHKERRQ(ierr);
90*94ab13aaSBarry Smith   if (J != B) {
91*94ab13aaSBarry Smith     ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
92*94ab13aaSBarry Smith     ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
93194405b3SBarry Smith   }
943a40ed3dSBarry Smith   PetscFunctionReturn(0);
9591627157SBarry Smith }
96