191627157SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 31e25c274SJed Brown #include <petscdm.h> /*I "petscdm.h" I*/ 491627157SBarry Smith 562cd874fSBarry Smith /* 662cd874fSBarry Smith MatFDColoringSetFunction() takes a function with four arguments, we want to use SNESComputeFunction() 762cd874fSBarry Smith since it logs function computation information. 862cd874fSBarry Smith */ 962cd874fSBarry Smith static PetscErrorCode SNESComputeFunctionCtx(SNES snes,Vec x,Vec f,void *ctx) 1062cd874fSBarry Smith { 1162cd874fSBarry Smith return SNESComputeFunction(snes,x,f); 1262cd874fSBarry Smith } 1362cd874fSBarry Smith 1491627157SBarry Smith /*@C 158d359177SBarry Smith SNESComputeJacobianDefaultColor - Computes the Jacobian using 16b4fc646aSLois Curfman McInnes finite differences and coloring to exploit matrix sparsity. 1791627157SBarry Smith 18fee21e36SBarry Smith Collective on SNES 19fee21e36SBarry Smith 20c7afd0dbSLois Curfman McInnes Input Parameters: 21c7afd0dbSLois Curfman McInnes + snes - nonlinear solver object 22c7afd0dbSLois Curfman McInnes . x1 - location at which to evaluate Jacobian 237fb41025SPeter Brune - ctx - MatFDColoring context or NULL 24c7afd0dbSLois Curfman McInnes 25c7afd0dbSLois Curfman McInnes Output Parameters: 26c7afd0dbSLois Curfman McInnes + J - Jacobian matrix (not altered in this routine) 2756744491SBarry Smith - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 28c7afd0dbSLois Curfman McInnes 2936851e7fSLois Curfman McInnes Level: intermediate 3036851e7fSLois Curfman McInnes 315620d6dcSBarry Smith Options Database Key: 325620d6dcSBarry Smith + -snes_fd_color_use_mat - use a matrix coloring from the explicit matrix nonzero pattern instead of from the DM providing the matrix 335620d6dcSBarry Smith . -snes_fd_color - Activates SNESComputeJacobianDefaultColor() in SNESSetFromOptions() 345620d6dcSBarry Smith . -mat_fd_coloring_err <err> - Sets <err> (square root of relative error in the function) 355620d6dcSBarry Smith . -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude 365620d6dcSBarry Smith - -mat_fd_type - Either wp or ds (see MATMFFD_WP or MATMFFD_DS) 375620d6dcSBarry Smith 385620d6dcSBarry Smith Notes: If the coloring is not provided through the context, this will first try to get the 397fb41025SPeter Brune coloring from the DM. If the DM type has no coloring routine, then it will try to 407fb41025SPeter Brune get the coloring from the matrix. This requires that the matrix have nonzero entries 41*f80563f6SBarry Smith precomputed. 42b0ae01b7SPeter Brune 43b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse 4491627157SBarry Smith 458d359177SBarry Smith .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault() 46ab637aeaSJed Brown MatFDColoringCreate(), MatFDColoringSetFunction() 47cb5b572fSBarry Smith 4891627157SBarry Smith @*/ 4995d750ceSBarry Smith 50d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 5191627157SBarry Smith { 527fb41025SPeter Brune MatFDColoring color = (MatFDColoring)ctx; 53dfbe8321SBarry Smith PetscErrorCode ierr; 544e269d77SPeter Brune DM dm; 55335efc43SPeter Brune MatColoring mc; 564e269d77SPeter Brune ISColoring iscoloring; 57b0ae01b7SPeter Brune PetscBool hascolor; 58aa2f1b4eSJed Brown PetscBool solvec,matcolor = PETSC_FALSE; 59dff777c9SBarry Smith 603a40ed3dSBarry Smith PetscFunctionBegin; 617fb41025SPeter Brune if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6); 6294ab13aaSBarry Smith else {ierr = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);} 6362cd874fSBarry Smith 644e269d77SPeter Brune if (!color) { 654e269d77SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 66b0ae01b7SPeter Brune ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); 67924833adSPeter Brune matcolor = PETSC_FALSE; 68c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr); 69c3138ed3SPeter Brune if (hascolor && !matcolor) { 70b412c318SBarry Smith ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); 7194ab13aaSBarry Smith ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 7262cd874fSBarry Smith ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); 734e269d77SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7494ab13aaSBarry Smith ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 75f86b9fbaSHong Zhang ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 76b0ae01b7SPeter Brune } else { 7794ab13aaSBarry Smith ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr); 78335efc43SPeter Brune ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr); 79335efc43SPeter Brune ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); 80335efc43SPeter Brune ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 81335efc43SPeter Brune ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr); 82335efc43SPeter Brune ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 8394ab13aaSBarry Smith ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 8462cd874fSBarry Smith ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); 85b0ae01b7SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 8694ab13aaSBarry Smith ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 87f86b9fbaSHong Zhang ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 88b0ae01b7SPeter Brune } 8994ab13aaSBarry Smith ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); 904108615fSPeter Brune ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); 914a9d489dSBarry Smith } 9295862db2SPeter Brune 93c89319d2SPeter Brune /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */ 94c89319d2SPeter Brune ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr); 95c89319d2SPeter Brune if (!snes->vec_rhs && solvec) { 9662cd874fSBarry Smith Vec F; 9762cd874fSBarry Smith ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr); 98432bb422SPeter Brune ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); 9995862db2SPeter Brune } 100d1e9a80fSBarry Smith ierr = MatFDColoringApply(B,color,x1,snes);CHKERRQ(ierr); 10194ab13aaSBarry Smith if (J != B) { 10294ab13aaSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10394ab13aaSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 104194405b3SBarry Smith } 1053a40ed3dSBarry Smith PetscFunctionReturn(0); 10691627157SBarry Smith } 107