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 } 130df40c35SBarry Smith static PetscErrorCode SNESComputeMFFunctionCtx(SNES snes,Vec x,Vec f,void *ctx) 140df40c35SBarry Smith { 150df40c35SBarry Smith return SNESComputeMFFunction(snes,x,f); 160df40c35SBarry Smith } 1762cd874fSBarry Smith 1891627157SBarry Smith /*@C 198d359177SBarry Smith SNESComputeJacobianDefaultColor - Computes the Jacobian using 20b4fc646aSLois Curfman McInnes finite differences and coloring to exploit matrix sparsity. 2191627157SBarry Smith 22fee21e36SBarry Smith Collective on SNES 23fee21e36SBarry Smith 24c7afd0dbSLois Curfman McInnes Input Parameters: 25c7afd0dbSLois Curfman McInnes + snes - nonlinear solver object 26c7afd0dbSLois Curfman McInnes . x1 - location at which to evaluate Jacobian 277fb41025SPeter Brune - ctx - MatFDColoring context or NULL 28c7afd0dbSLois Curfman McInnes 29c7afd0dbSLois Curfman McInnes Output Parameters: 30c7afd0dbSLois Curfman McInnes + J - Jacobian matrix (not altered in this routine) 3156744491SBarry Smith - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 32c7afd0dbSLois Curfman McInnes 3336851e7fSLois Curfman McInnes Level: intermediate 3436851e7fSLois Curfman McInnes 355620d6dcSBarry Smith Options Database Key: 365620d6dcSBarry Smith + -snes_fd_color_use_mat - use a matrix coloring from the explicit matrix nonzero pattern instead of from the DM providing the matrix 375620d6dcSBarry Smith . -snes_fd_color - Activates SNESComputeJacobianDefaultColor() in SNESSetFromOptions() 385620d6dcSBarry Smith . -mat_fd_coloring_err <err> - Sets <err> (square root of relative error in the function) 395620d6dcSBarry Smith . -mat_fd_coloring_umin <umin> - Sets umin, the minimum allowable u-value magnitude 40ec5066bdSBarry Smith . -mat_fd_type - Either wp or ds (see MATMFFD_WP or MATMFFD_DS) 41ec5066bdSBarry Smith . -snes_mf_operator - Use matrix free application of Jacobian 42*a5b23f4aSJose E. Roman - -snes_mf - Use matrix free Jacobian with no explicit Jacobian representation 435620d6dcSBarry Smith 4495452b02SPatrick Sanan Notes: 4595452b02SPatrick Sanan If the coloring is not provided through the context, this will first try to get the 467fb41025SPeter Brune coloring from the DM. If the DM type has no coloring routine, then it will try to 477fb41025SPeter Brune get the coloring from the matrix. This requires that the matrix have nonzero entries 48f80563f6SBarry Smith precomputed. 49b0ae01b7SPeter Brune 500df40c35SBarry Smith SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free via SNESSetUseMatrixFree(), 51*a5b23f4aSJose E. Roman and computing explicitly with finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation 520df40c35SBarry Smith and the MatFDColoring object, see src/ts/tutorials/autodiff/ex16adj_tl.cxx 53ec5066bdSBarry Smith 54ec5066bdSBarry Smith .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault(), SNESSetUseMatrixFree(), 55ab637aeaSJed Brown MatFDColoringCreate(), MatFDColoringSetFunction() 56cb5b572fSBarry Smith 5791627157SBarry Smith @*/ 58d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 5991627157SBarry Smith { 607fb41025SPeter Brune MatFDColoring color = (MatFDColoring)ctx; 61dfbe8321SBarry Smith PetscErrorCode ierr; 624e269d77SPeter Brune DM dm; 63335efc43SPeter Brune MatColoring mc; 644e269d77SPeter Brune ISColoring iscoloring; 65b0ae01b7SPeter Brune PetscBool hascolor; 66aa2f1b4eSJed Brown PetscBool solvec,matcolor = PETSC_FALSE; 670df40c35SBarry Smith DMSNES dms; 68dff777c9SBarry Smith 693a40ed3dSBarry Smith PetscFunctionBegin; 70064a246eSJacob Faibussowitsch if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,5); 71d27375acSBarry Smith if (!color) {ierr = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);} 7262cd874fSBarry Smith 734e269d77SPeter Brune if (!color) { 744e269d77SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 75b0ae01b7SPeter Brune ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); 76924833adSPeter Brune matcolor = PETSC_FALSE; 77c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr); 78c3138ed3SPeter Brune if (hascolor && !matcolor) { 79b412c318SBarry Smith ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); 80b0ae01b7SPeter Brune } else { 8194ab13aaSBarry Smith ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr); 82335efc43SPeter Brune ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr); 83335efc43SPeter Brune ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); 84335efc43SPeter Brune ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 85335efc43SPeter Brune ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr); 86335efc43SPeter Brune ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 870df40c35SBarry Smith } 8894ab13aaSBarry Smith ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); 890df40c35SBarry Smith ierr = DMGetDMSNES(dm,&dms);CHKERRQ(ierr); 900df40c35SBarry Smith if (dms->ops->computemffunction) { 910df40c35SBarry Smith ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeMFFunctionCtx,NULL);CHKERRQ(ierr); 920df40c35SBarry Smith } else { 9362cd874fSBarry Smith ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); 940df40c35SBarry Smith } 95b0ae01b7SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 9694ab13aaSBarry Smith ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); 97f86b9fbaSHong Zhang ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 9894ab13aaSBarry Smith ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); 994108615fSPeter Brune ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); 1004a9d489dSBarry Smith } 10195862db2SPeter Brune 102c89319d2SPeter Brune /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */ 103c89319d2SPeter Brune ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr); 104c89319d2SPeter Brune if (!snes->vec_rhs && solvec) { 10562cd874fSBarry Smith Vec F; 10662cd874fSBarry Smith ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr); 107432bb422SPeter Brune ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); 10895862db2SPeter Brune } 109d1e9a80fSBarry Smith ierr = MatFDColoringApply(B,color,x1,snes);CHKERRQ(ierr); 11094ab13aaSBarry Smith if (J != B) { 11194ab13aaSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11294ab13aaSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 113194405b3SBarry Smith } 1143a40ed3dSBarry Smith PetscFunctionReturn(0); 11591627157SBarry Smith } 116