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 15243e2ce7SPeter Brune - ctx - ignored context parameter 16c7afd0dbSLois Curfman McInnes 17c7afd0dbSLois Curfman McInnes Output Parameters: 18c7afd0dbSLois Curfman McInnes + J - Jacobian matrix (not altered in this routine) 19c7afd0dbSLois Curfman McInnes . B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 20c7afd0dbSLois Curfman McInnes - flag - flag indicating whether the matrix sparsity structure has changed 21c7afd0dbSLois Curfman McInnes 2236851e7fSLois Curfman McInnes Level: intermediate 2336851e7fSLois Curfman McInnes 24243e2ce7SPeter Brune .notes: This will first try to get the coloring from the DM. If the DM type 25b0ae01b7SPeter Brune has no coloring routine, then it will try to get the coloring from the matrix. This 26b0ae01b7SPeter Brune requires that the matrix have nonzero entries precomputed, such as in 27b0ae01b7SPeter Brune snes/examples/tutorials/ex45.c. 28b0ae01b7SPeter Brune 29b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse 3091627157SBarry Smith 31b4fc646aSLois Curfman McInnes .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESDefaultComputeJacobian() 32ab637aeaSJed Brown MatFDColoringCreate(), MatFDColoringSetFunction() 33cb5b572fSBarry Smith 3491627157SBarry Smith @*/ 3595d750ceSBarry Smith 367087cfbeSBarry Smith PetscErrorCode SNESDefaultComputeJacobianColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 3791627157SBarry Smith { 38243e2ce7SPeter Brune MatFDColoring color = PETSC_NULL; 39dfbe8321SBarry Smith PetscErrorCode ierr; 404e269d77SPeter Brune DM dm; 414e269d77SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 424e269d77SPeter Brune Vec F; 434e269d77SPeter Brune void *funcctx; 444e269d77SPeter Brune ISColoring iscoloring; 45b0ae01b7SPeter Brune PetscBool hascolor; 46dff777c9SBarry Smith 473a40ed3dSBarry Smith PetscFunctionBegin; 484e269d77SPeter Brune ierr = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject *)&color);CHKERRQ(ierr); 4992abec31SBarry Smith *flag = SAME_NONZERO_PATTERN; 50*22d28d08SBarry Smith ierr = SNESGetFunction(snes,&F,&func,&funcctx);CHKERRQ(ierr); 514e269d77SPeter Brune if (!color) { 524e269d77SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 53b0ae01b7SPeter Brune ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); 54b0ae01b7SPeter Brune if (hascolor) { 554e269d77SPeter Brune ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); 564e269d77SPeter Brune ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr); 574e269d77SPeter Brune ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 584e269d77SPeter Brune ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 594e269d77SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 60b0ae01b7SPeter Brune } else { 61b0ae01b7SPeter Brune ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 62b0ae01b7SPeter Brune ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr); 630171d955SPeter Brune ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 64b0ae01b7SPeter Brune ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr); 65b0ae01b7SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 66b0ae01b7SPeter Brune } 674e269d77SPeter Brune ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); 684108615fSPeter Brune ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); 694a9d489dSBarry Smith } 7095862db2SPeter Brune 7195862db2SPeter Brune /* F is only usable if there is no RHS on the SNES */ 7295862db2SPeter Brune if (!snes->vec_rhs) { 73432bb422SPeter Brune ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); 7495862db2SPeter Brune } 75005c665bSBarry Smith ierr = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr); 7632dfb669SBarry Smith if (*J != *B) { 77194405b3SBarry Smith ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 78194405b3SBarry Smith ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 79194405b3SBarry Smith } 803a40ed3dSBarry Smith PetscFunctionReturn(0); 8191627157SBarry Smith } 82