xref: /petsc/src/snes/interface/snesj2.c (revision c5929fdf3082647d199855a5c1d0286204349b03)
191627157SBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>    /*I  "petscsnes.h"  I*/
31e25c274SJed Brown #include <petscdm.h>                   /*I  "petscdm.h"    I*/
491627157SBarry Smith 
562cd874fSBarry Smith /*
662cd874fSBarry Smith    MatFDColoringSetFunction() takes a function with four arguments, we want to use SNESComputeFunction()
762cd874fSBarry Smith    since it logs function computation information.
862cd874fSBarry Smith */
962cd874fSBarry Smith static PetscErrorCode SNESComputeFunctionCtx(SNES snes,Vec x,Vec f,void *ctx)
1062cd874fSBarry Smith {
1162cd874fSBarry Smith   return SNESComputeFunction(snes,x,f);
1262cd874fSBarry Smith }
1362cd874fSBarry Smith 
144a2ae208SSatish Balay #undef __FUNCT__
158d359177SBarry Smith #define __FUNCT__ "SNESComputeJacobianDefaultColor"
1691627157SBarry Smith /*@C
178d359177SBarry Smith     SNESComputeJacobianDefaultColor - Computes the Jacobian using
18b4fc646aSLois Curfman McInnes     finite differences and coloring to exploit matrix sparsity.
1991627157SBarry Smith 
20fee21e36SBarry Smith     Collective on SNES
21fee21e36SBarry Smith 
22c7afd0dbSLois Curfman McInnes     Input Parameters:
23c7afd0dbSLois Curfman McInnes +   snes - nonlinear solver object
24c7afd0dbSLois Curfman McInnes .   x1 - location at which to evaluate Jacobian
257fb41025SPeter Brune -   ctx - MatFDColoring context or NULL
26c7afd0dbSLois Curfman McInnes 
27c7afd0dbSLois Curfman McInnes     Output Parameters:
28c7afd0dbSLois Curfman McInnes +   J - Jacobian matrix (not altered in this routine)
2956744491SBarry Smith -   B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
30c7afd0dbSLois Curfman McInnes 
3136851e7fSLois Curfman McInnes     Level: intermediate
3236851e7fSLois Curfman McInnes 
335620d6dcSBarry Smith    Options Database Key:
345620d6dcSBarry Smith +  -snes_fd_color_use_mat - use a matrix coloring from the explicit matrix nonzero pattern instead of from the DM providing the matrix
355620d6dcSBarry Smith .  -snes_fd_color - Activates SNESComputeJacobianDefaultColor() in SNESSetFromOptions()
365620d6dcSBarry Smith .  -mat_fd_coloring_err <err> - Sets <err> (square root of relative error in the function)
375620d6dcSBarry Smith .  -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude
385620d6dcSBarry Smith -  -mat_fd_type - Either wp or ds (see MATMFFD_WP or MATMFFD_DS)
395620d6dcSBarry Smith 
405620d6dcSBarry Smith     Notes: If the coloring is not provided through the context, this will first try to get the
417fb41025SPeter Brune         coloring from the DM.  If the DM type has no coloring routine, then it will try to
427fb41025SPeter Brune         get the coloring from the matrix.  This requires that the matrix have nonzero entries
437086a01eSPeter Brune         precomputed.  This is discouraged, as MatColoringApply() is not parallel by default.
44b0ae01b7SPeter Brune 
45b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse
4691627157SBarry Smith 
478d359177SBarry Smith .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault()
48ab637aeaSJed Brown           MatFDColoringCreate(), MatFDColoringSetFunction()
49cb5b572fSBarry Smith 
5091627157SBarry Smith @*/
5195d750ceSBarry Smith 
52d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
5391627157SBarry Smith {
547fb41025SPeter Brune   MatFDColoring  color = (MatFDColoring)ctx;
55dfbe8321SBarry Smith   PetscErrorCode ierr;
564e269d77SPeter Brune   DM             dm;
57335efc43SPeter Brune   MatColoring    mc;
584e269d77SPeter Brune   ISColoring     iscoloring;
59b0ae01b7SPeter Brune   PetscBool      hascolor;
60aa2f1b4eSJed Brown   PetscBool      solvec,matcolor = PETSC_FALSE;
61dff777c9SBarry Smith 
623a40ed3dSBarry Smith   PetscFunctionBegin;
637fb41025SPeter Brune   if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6);
6494ab13aaSBarry Smith   else {ierr  = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);}
6562cd874fSBarry Smith 
664e269d77SPeter Brune   if (!color) {
674e269d77SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
68b0ae01b7SPeter Brune     ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr);
69924833adSPeter Brune     matcolor = PETSC_FALSE;
70*c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr);
71c3138ed3SPeter Brune     if (hascolor && !matcolor) {
72b412c318SBarry Smith       ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr);
7394ab13aaSBarry Smith       ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr);
7462cd874fSBarry Smith       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr);
754e269d77SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7694ab13aaSBarry Smith       ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr);
77f86b9fbaSHong Zhang       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
78b0ae01b7SPeter Brune     } else {
7994ab13aaSBarry Smith       ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr);
80335efc43SPeter Brune       ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr);
81335efc43SPeter Brune       ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr);
82335efc43SPeter Brune       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
83335efc43SPeter Brune       ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr);
84335efc43SPeter Brune       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
8594ab13aaSBarry Smith       ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr);
8662cd874fSBarry Smith       ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr);
87b0ae01b7SPeter Brune       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
8894ab13aaSBarry Smith       ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr);
89f86b9fbaSHong Zhang       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
90b0ae01b7SPeter Brune     }
9194ab13aaSBarry Smith     ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr);
924108615fSPeter Brune     ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr);
934a9d489dSBarry Smith   }
9495862db2SPeter Brune 
95c89319d2SPeter Brune   /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */
96c89319d2SPeter Brune   ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr);
97c89319d2SPeter Brune   if (!snes->vec_rhs && solvec) {
9862cd874fSBarry Smith     Vec F;
9962cd874fSBarry Smith     ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr);
100432bb422SPeter Brune     ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr);
10195862db2SPeter Brune   }
102d1e9a80fSBarry Smith   ierr = MatFDColoringApply(B,color,x1,snes);CHKERRQ(ierr);
10394ab13aaSBarry Smith   if (J != B) {
10494ab13aaSBarry Smith     ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10594ab13aaSBarry Smith     ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
106194405b3SBarry Smith   }
1073a40ed3dSBarry Smith   PetscFunctionReturn(0);
10891627157SBarry Smith }
109