Actual source code: snesj2.c

petsc-3.9.4 2018-09-11
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)

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

 43: .keywords: SNES, finite differences, Jacobian, coloring, sparse

 45: .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault()
 46:           MatFDColoringCreate(), MatFDColoringSetFunction()

 48: @*/

 50: PetscErrorCode  SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
 51: {
 52:   MatFDColoring  color = (MatFDColoring)ctx;
 54:   DM             dm;
 55:   MatColoring    mc;
 56:   ISColoring     iscoloring;
 57:   PetscBool      hascolor;
 58:   PetscBool      solvec,matcolor = PETSC_FALSE;

 62:   else {PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);}

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

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