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 36*ec5066bdSBarry Smith . -mat_fd_type - Either wp or ds (see MATMFFD_WP or MATMFFD_DS) 37*ec5066bdSBarry Smith . -snes_mf_operator - Use matrix free application of Jacobian 38*ec5066bdSBarry Smith - -snes_mf - Use matrix free Jacobian with not explicit Jacobian represenation 395620d6dcSBarry Smith 4095452b02SPatrick Sanan Notes: 4195452b02SPatrick Sanan If the coloring is not provided through the context, this will first try to get the 427fb41025SPeter Brune coloring from the DM. If the DM type has no coloring routine, then it will try to 437fb41025SPeter Brune get the coloring from the matrix. This requires that the matrix have nonzero entries 44f80563f6SBarry Smith precomputed. 45b0ae01b7SPeter Brune 46*ec5066bdSBarry Smith SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free via SNESSetUseMatrixFree, 47*ec5066bdSBarry Smith and computing explictly with finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 48*ec5066bdSBarry Smith 49*ec5066bdSBarry Smith 50*ec5066bdSBarry Smith .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault(), SNESSetUseMatrixFree(), 51ab637aeaSJed Brown MatFDColoringCreate(), MatFDColoringSetFunction() 52cb5b572fSBarry Smith 5391627157SBarry Smith @*/ 5495d750ceSBarry Smith 55d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 5691627157SBarry Smith { 577fb41025SPeter Brune MatFDColoring color = (MatFDColoring)ctx; 58dfbe8321SBarry Smith PetscErrorCode ierr; 594e269d77SPeter Brune DM dm; 60335efc43SPeter Brune MatColoring mc; 614e269d77SPeter Brune ISColoring iscoloring; 62b0ae01b7SPeter Brune PetscBool hascolor; 63aa2f1b4eSJed Brown PetscBool solvec,matcolor = PETSC_FALSE; 64dff777c9SBarry Smith 653a40ed3dSBarry Smith PetscFunctionBegin; 667fb41025SPeter Brune if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6); 67d27375acSBarry Smith if (!color) {ierr = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);} 6862cd874fSBarry Smith 694e269d77SPeter Brune if (!color) { 704e269d77SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 71b0ae01b7SPeter Brune ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); 72924833adSPeter Brune matcolor = PETSC_FALSE; 73c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr); 74c3138ed3SPeter Brune if (hascolor && !matcolor) { 75b412c318SBarry Smith ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); 7694ab13aaSBarry Smith ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 7762cd874fSBarry Smith ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); 784e269d77SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7994ab13aaSBarry Smith ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 80f86b9fbaSHong Zhang ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 81b0ae01b7SPeter Brune } else { 8294ab13aaSBarry Smith ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr); 83335efc43SPeter Brune ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr); 84335efc43SPeter Brune ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); 85335efc43SPeter Brune ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 86335efc43SPeter Brune ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr); 87335efc43SPeter Brune ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 8894ab13aaSBarry Smith ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 8962cd874fSBarry Smith ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); 90b0ae01b7SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 9194ab13aaSBarry Smith ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 92f86b9fbaSHong Zhang ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 93b0ae01b7SPeter Brune } 9494ab13aaSBarry Smith ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); 954108615fSPeter Brune ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); 964a9d489dSBarry Smith } 9795862db2SPeter Brune 98c89319d2SPeter Brune /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */ 99c89319d2SPeter Brune ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr); 100c89319d2SPeter Brune if (!snes->vec_rhs && solvec) { 10162cd874fSBarry Smith Vec F; 10262cd874fSBarry Smith ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr); 103432bb422SPeter Brune ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); 10495862db2SPeter Brune } 105d1e9a80fSBarry Smith ierr = MatFDColoringApply(B,color,x1,snes);CHKERRQ(ierr); 10694ab13aaSBarry Smith if (J != B) { 10794ab13aaSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10894ab13aaSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 109194405b3SBarry Smith } 1103a40ed3dSBarry Smith PetscFunctionReturn(0); 11191627157SBarry Smith } 112