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 22 Level: intermediate 23 24 .notes: If the coloring is not provided through the context, this will first try to get the 25 coloring from the DM. If the DM type has no coloring routine, then it will try to 26 get the coloring from the matrix. This requires that the matrix have nonzero entries 27 precomputed. This is discouraged, as MatColoringApply() is not parallel by default. 28 29 .keywords: SNES, finite differences, Jacobian, coloring, sparse 30 31 .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault() 32 MatFDColoringCreate(), MatFDColoringSetFunction() 33 34 @*/ 35 36 PetscErrorCode SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 37 { 38 MatFDColoring color = (MatFDColoring)ctx; 39 PetscErrorCode ierr; 40 DM dm; 41 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 42 Vec F; 43 void *funcctx; 44 MatColoring mc; 45 ISColoring iscoloring; 46 PetscBool hascolor; 47 PetscBool solvec,matcolor = PETSC_FALSE; 48 49 PetscFunctionBegin; 50 if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6); 51 else {ierr = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);} 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 matcolor = PETSC_FALSE; 57 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr); 58 if (hascolor && !matcolor) { 59 ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); 60 ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 61 ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 62 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 63 ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 64 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 65 } else { 66 ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr); 67 ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr); 68 ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); 69 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 70 ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr); 71 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 72 ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 73 ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr); 74 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 75 ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 76 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 77 } 78 ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); 79 ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); 80 } 81 82 /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */ 83 ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr); 84 if (!snes->vec_rhs && solvec) { 85 ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); 86 } 87 ierr = MatFDColoringApply(B,color,x1,snes);CHKERRQ(ierr); 88 if (J != B) { 89 ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 90 ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 91 } 92 PetscFunctionReturn(0); 93 } 94