xref: /petsc/src/snes/interface/snesj2.c (revision 0a6ece4efbe0fc0d64b36d89d274ad0f89f90441)
1 
2 #include <petsc-private/snesimpl.h>    /*I  "petscsnes.h"  I*/
3 #include <petscdm.h>                   /*I  "petscdm.h"    I*/
4 
5 #undef __FUNCT__
6 #define __FUNCT__ "SNESComputeJacobianDefaultColor"
7 /*@C
8     SNESComputeJacobianDefaultColor - Computes the Jacobian using
9     finite differences and coloring to exploit matrix sparsity.
10 
11     Collective on SNES
12 
13     Input Parameters:
14 +   snes - nonlinear solver object
15 .   x1 - location at which to evaluate Jacobian
16 -   ctx - MatFDColoring context or NULL
17 
18     Output Parameters:
19 +   J - Jacobian matrix (not altered in this routine)
20 .   B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
21 -   flag - flag indicating whether the matrix sparsity structure has changed
22 
23     Level: intermediate
24 
25 .notes: If the coloring is not provided through the context, this will first try to get the
26         coloring from the DM.  If the DM type has no coloring routine, then it will try to
27         get the coloring from the matrix.  This requires that the matrix have nonzero entries
28         precomputed.  This is discouraged, as MatGetColoring() is not parallel.
29 
30 .keywords: SNES, finite differences, Jacobian, coloring, sparse
31 
32 .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault()
33           MatFDColoringCreate(), MatFDColoringSetFunction()
34 
35 @*/
36 
37 PetscErrorCode  SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
38 {
39   MatFDColoring  color = (MatFDColoring)ctx;
40   PetscErrorCode ierr;
41   DM             dm;
42   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
43   Vec            F;
44   void           *funcctx;
45   ISColoring     iscoloring;
46   PetscBool      hascolor;
47 
48   PetscFunctionBegin;
49   if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6);
50   else {ierr  = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);}
51   *flag = SAME_NONZERO_PATTERN;
52   ierr  = SNESGetFunction(snes,&F,&func,&funcctx);CHKERRQ(ierr);
53   if (!color) {
54     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
55     ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr);
56     if (hascolor) {
57       ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr);
58       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
59       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
60       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
61       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
62     } else {
63       ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
64       ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr);
65       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
66       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr);
67       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
68     }
69     ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr);
70     ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr);
71   }
72 
73   /* F is only usable if there is no RHS on the SNES */
74   if (!snes->vec_rhs) {
75     ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr);
76   }
77   ierr = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr);
78   if (*J != *B) {
79     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
80     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
81   }
82   PetscFunctionReturn(0);
83 }
84