Date: 2013-07-02T14:49:21+00:00

Actual source code: snesj2.c
petsc-3.4.2 2013-07-02

      2: #include <petsc-private/snesimpl.h>    /*I  "petscsnes.h"  I*/
      3: #include <petscdm.h>                   /*I  "petscdm.h"    I*/

      7: /*@C
      8:     SNESComputeJacobianDefaultColor - Computes the Jacobian using
      9:     finite differences and coloring to exploit matrix sparsity.

     11:     Collective on SNES

     13:     Input Parameters:
     14: +   snes - nonlinear solver object
     15: .   x1 - location at which to evaluate Jacobian
     16: -   ctx - MatFDColoring context or NULL

     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

     23:     Level: intermediate

     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.

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

     32: .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault()
     33:           MatFDColoringCreate(), MatFDColoringSetFunction()

     35: @*/

     37: PetscErrorCode  SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
     38: {
     39:   MatFDColoring  color = (MatFDColoring)ctx;
     41:   DM             dm;
     42:   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
     43:   Vec            F;
     44:   void           *funcctx;
     45:   ISColoring     iscoloring;
     46:   PetscBool      hascolor;

     50:   else {PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject*)&color);}
     51:   *flag = SAME_NONZERO_PATTERN;
     52:   SNESGetFunction(snes,&F,&func,&funcctx);
     53:   if (!color) {
     54:     SNESGetDM(snes,&dm);
     55:     DMHasColoring(dm,&hascolor);
     56:     if (hascolor) {
     57:       DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);
     58:       MatFDColoringCreate(*B,iscoloring,&color);
     59:       ISColoringDestroy(&iscoloring);
     60:       MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);
     61:       MatFDColoringSetFromOptions(color);
     62:     } else {
     63:       MatGetColoring(*B,MATCOLORINGSL,&iscoloring);
     64:       MatFDColoringCreate(*B,iscoloring,&color);
     65:       ISColoringDestroy(&iscoloring);
     66:       MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);
     67:       MatFDColoringSetFromOptions(color);
     68:     }
     69:     PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);
     70:     PetscObjectDereference((PetscObject)color);
     71:   }

     73:   /* F is only usable if there is no RHS on the SNES */
     74:   if (!snes->vec_rhs) {
     75:     MatFDColoringSetF(color,F);
     76:   }
     77:   MatFDColoringApply(*B,color,x1,flag,snes);
     78:   if (*J != *B) {
     79:     MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);
     80:     MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);
     81:   }
     82:   return(0);
     83: }