Actual source code: snesj2.c
petsc-3.13.6 2020-09-29
Report Typos and Errors

      2:  #include <petsc/private/snesimpl.h>
      3:  #include <petscdm.h>

      5: /*
      6:    MatFDColoringSetFunction() takes a function with four arguments, we want to use SNESComputeFunction()
      7:    since it logs function computation information.
      8: */
      9: static PetscErrorCode SNESComputeFunctionCtx(SNES snes,Vec x,Vec f,void *ctx)
     10: {
     11:   return SNESComputeFunction(snes,x,f);
     12: }

     14: /*@C
     15:     SNESComputeJacobianDefaultColor - Computes the Jacobian using
     16:     finite differences and coloring to exploit matrix sparsity.

     18:     Collective on SNES

     20:     Input Parameters:
     21: +   snes - nonlinear solver object
     22: .   x1 - location at which to evaluate Jacobian
     23: -   ctx - MatFDColoring context or NULL

     25:     Output Parameters:
     26: +   J - Jacobian matrix (not altered in this routine)
     27: -   B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)

     29:     Level: intermediate

     31:    Options Database Key:
     32: +  -snes_fd_color_use_mat - use a matrix coloring from the explicit matrix nonzero pattern instead of from the DM providing the matrix
     33: .  -snes_fd_color - Activates SNESComputeJacobianDefaultColor() in SNESSetFromOptions()
     34: .  -mat_fd_coloring_err <err> - Sets <err> (square root of relative error in the function)
     35: .  -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude
     36: .  -mat_fd_type - Either wp or ds (see MATMFFD_WP or MATMFFD_DS)
     37: .  -snes_mf_operator - Use matrix free Section 1.5 Writing Application Codes with PETSc of Jacobian
     38: -  -snes_mf - Use matrix free Jacobian with not explicit Jacobian represenation

     40:     Notes:
     41:         If the coloring is not provided through the context, this will first try to get the
     42:         coloring from the DM.  If the DM type has no coloring routine, then it will try to
     43:         get the coloring from the matrix.  This requires that the matrix have nonzero entries
     44:         precomputed.

     46:        SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free via SNESSetUseMatrixFree,
     47:        and computing explictly with finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.

     50: .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault(), SNESSetUseMatrixFree(),
     51:           MatFDColoringCreate(), MatFDColoringSetFunction()

     53: @*/

     55: PetscErrorCode  SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
     56: {
     57:   MatFDColoring  color = (MatFDColoring)ctx;
     59:   DM             dm;
     60:   MatColoring    mc;
     61:   ISColoring     iscoloring;
     62:   PetscBool      hascolor;
     63:   PetscBool      solvec,matcolor = PETSC_FALSE;

     67:   if (!color) {PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);}

     69:   if (!color) {
     70:     SNESGetDM(snes,&dm);
     71:     DMHasColoring(dm,&hascolor);
     72:     matcolor = PETSC_FALSE;
     73:     PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);
     74:     if (hascolor && !matcolor) {
     75:       DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);
     76:       MatFDColoringCreate(B,iscoloring,&color);
     77:       MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);
     78:       MatFDColoringSetFromOptions(color);
     79:       MatFDColoringSetUp(B,iscoloring,color);
     80:       ISColoringDestroy(&iscoloring);
     81:     } else {
     82:       MatColoringCreate(B,&mc);
     83:       MatColoringSetDistance(mc,2);
     84:       MatColoringSetType(mc,MATCOLORINGSL);
     85:       MatColoringSetFromOptions(mc);
     86:       MatColoringApply(mc,&iscoloring);
     87:       MatColoringDestroy(&mc);
     88:       MatFDColoringCreate(B,iscoloring,&color);
     89:       MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);
     90:       MatFDColoringSetFromOptions(color);
     91:       MatFDColoringSetUp(B,iscoloring,color);
     92:       ISColoringDestroy(&iscoloring);
     93:     }
     94:     PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);
     95:     PetscObjectDereference((PetscObject)color);
     96:   }

     98:   /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */
     99:   VecEqual(x1,snes->vec_sol,&solvec);
    100:   if (!snes->vec_rhs && solvec) {
    101:     Vec F;
    102:     SNESGetFunction(snes,&F,NULL,NULL);
    103:     MatFDColoringSetF(color,F);
    104:   }
    105:   MatFDColoringApply(B,color,x1,snes);
    106:   if (J != B) {
    107:     MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);
    108:     MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);
    109:   }
    110:   return(0);
    111: }