191627157SBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 391627157SBarry Smith 44a2ae208SSatish Balay #undef __FUNCT__ 54a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultComputeJacobianColor" 691627157SBarry Smith /*@C 72d0c0e3bSBarry Smith SNESDefaultComputeJacobianColor - Computes the Jacobian using 8b4fc646aSLois Curfman McInnes finite differences and coloring to exploit matrix sparsity. 991627157SBarry Smith 10fee21e36SBarry Smith Collective on SNES 11fee21e36SBarry Smith 12c7afd0dbSLois Curfman McInnes Input Parameters: 13c7afd0dbSLois Curfman McInnes + snes - nonlinear solver object 14c7afd0dbSLois Curfman McInnes . x1 - location at which to evaluate Jacobian 15c7afd0dbSLois Curfman McInnes - ctx - coloring context, where ctx must have type MatFDColoring, 16c7afd0dbSLois Curfman McInnes as created via MatFDColoringCreate() 17c7afd0dbSLois Curfman McInnes 18c7afd0dbSLois Curfman McInnes Output Parameters: 19c7afd0dbSLois Curfman McInnes + J - Jacobian matrix (not altered in this routine) 20c7afd0dbSLois Curfman McInnes . B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 21c7afd0dbSLois Curfman McInnes - flag - flag indicating whether the matrix sparsity structure has changed 22c7afd0dbSLois Curfman McInnes 2336851e7fSLois Curfman McInnes Level: intermediate 2436851e7fSLois Curfman McInnes 25b0ae01b7SPeter Brune .notes: If ctx is not provided, this will try to get the coloring from the DM. If the DM type 26b0ae01b7SPeter Brune has no coloring routine, then it will try to get the coloring from the matrix. This 27b0ae01b7SPeter Brune requires that the matrix have nonzero entries precomputed, such as in 28b0ae01b7SPeter Brune snes/examples/tutorials/ex45.c. 29b0ae01b7SPeter Brune 30b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse 3191627157SBarry Smith 32b4fc646aSLois Curfman McInnes .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESDefaultComputeJacobian() 33ab637aeaSJed Brown MatFDColoringCreate(), MatFDColoringSetFunction() 34cb5b572fSBarry Smith 3591627157SBarry Smith @*/ 3695d750ceSBarry Smith 377087cfbeSBarry Smith PetscErrorCode SNESDefaultComputeJacobianColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 3891627157SBarry Smith { 39b0ae01b7SPeter Brune MatFDColoring color = (MatFDColoring)ctx; 40dfbe8321SBarry Smith PetscErrorCode ierr; 41*4e269d77SPeter Brune DM dm; 42*4e269d77SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 43*4e269d77SPeter Brune Vec F; 44*4e269d77SPeter Brune void *funcctx; 45*4e269d77SPeter Brune ISColoring iscoloring; 46b0ae01b7SPeter Brune PetscBool hascolor; 47dff777c9SBarry Smith 483a40ed3dSBarry Smith PetscFunctionBegin; 49b0ae01b7SPeter Brune if (color) { 50b0ae01b7SPeter Brune PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6); 51b0ae01b7SPeter Brune } else { 52*4e269d77SPeter Brune ierr = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject *)&color);CHKERRQ(ierr); 53b0ae01b7SPeter Brune } 5492abec31SBarry Smith *flag = SAME_NONZERO_PATTERN; 55*4e269d77SPeter Brune ierr = SNESGetFunction(snes,&F,&func,&funcctx); 56*4e269d77SPeter Brune if (!color) { 57*4e269d77SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 58b0ae01b7SPeter Brune ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); 59b0ae01b7SPeter Brune if (hascolor) { 60*4e269d77SPeter Brune ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); 61*4e269d77SPeter Brune ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr); 62*4e269d77SPeter Brune ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 63*4e269d77SPeter Brune ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 64*4e269d77SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 65b0ae01b7SPeter Brune } else { 66b0ae01b7SPeter Brune ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 67b0ae01b7SPeter Brune ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr); 68b0ae01b7SPeter Brune ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr); 69b0ae01b7SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 70b0ae01b7SPeter Brune } 71*4e269d77SPeter Brune ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); 724a9d489dSBarry Smith } 73*4e269d77SPeter Brune ierr = MatFDColoringSetF(color,PETSC_NULL);CHKERRQ(ierr); 74005c665bSBarry Smith ierr = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr); 7532dfb669SBarry Smith if (*J != *B) { 76194405b3SBarry Smith ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 77194405b3SBarry Smith ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 78194405b3SBarry Smith } 793a40ed3dSBarry Smith PetscFunctionReturn(0); 8091627157SBarry Smith } 81