1 2 #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 3 #include <petscdm.h> /*I "petscdm.h" I*/ 4 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 } 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "SNESComputeJacobianDefaultColor" 16 /*@C 17 SNESComputeJacobianDefaultColor - Computes the Jacobian using 18 finite differences and coloring to exploit matrix sparsity. 19 20 Collective on SNES 21 22 Input Parameters: 23 + snes - nonlinear solver object 24 . x1 - location at which to evaluate Jacobian 25 - ctx - MatFDColoring context or NULL 26 27 Output Parameters: 28 + J - Jacobian matrix (not altered in this routine) 29 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 30 31 Level: intermediate 32 33 Options Database Key: 34 + -snes_fd_color_use_mat - use a matrix coloring from the explicit matrix nonzero pattern instead of from the DM providing the matrix 35 . -snes_fd_color - Activates SNESComputeJacobianDefaultColor() in SNESSetFromOptions() 36 . -mat_fd_coloring_err <err> - Sets <err> (square root of relative error in the function) 37 . -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude 38 - -mat_fd_type - Either wp or ds (see MATMFFD_WP or MATMFFD_DS) 39 40 Notes: If the coloring is not provided through the context, this will first try to get the 41 coloring from the DM. If the DM type has no coloring routine, then it will try to 42 get the coloring from the matrix. This requires that the matrix have nonzero entries 43 precomputed. This is discouraged, as MatColoringApply() is not parallel by default. 44 45 .keywords: SNES, finite differences, Jacobian, coloring, sparse 46 47 .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault() 48 MatFDColoringCreate(), MatFDColoringSetFunction() 49 50 @*/ 51 52 PetscErrorCode SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 53 { 54 MatFDColoring color = (MatFDColoring)ctx; 55 PetscErrorCode ierr; 56 DM dm; 57 MatColoring mc; 58 ISColoring iscoloring; 59 PetscBool hascolor; 60 PetscBool solvec,matcolor = PETSC_FALSE; 61 62 PetscFunctionBegin; 63 if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6); 64 else {ierr = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);} 65 66 if (!color) { 67 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 68 ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); 69 matcolor = PETSC_FALSE; 70 ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr); 71 if (hascolor && !matcolor) { 72 ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); 73 ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 74 ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); 75 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 76 ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 77 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 78 } else { 79 ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr); 80 ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr); 81 ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); 82 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 83 ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr); 84 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 85 ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 86 ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); 87 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 88 ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 89 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 90 } 91 ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); 92 ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); 93 } 94 95 /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */ 96 ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr); 97 if (!snes->vec_rhs && solvec) { 98 Vec F; 99 ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr); 100 ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); 101 } 102 ierr = MatFDColoringApply(B,color,x1,snes);CHKERRQ(ierr); 103 if (J != B) { 104 ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 105 ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 106 } 107 PetscFunctionReturn(0); 108 } 109