191627157SBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 31e25c274SJed Brown #include <petscdm.h> /*I "petscdm.h" I*/ 491627157SBarry Smith 54a2ae208SSatish Balay #undef __FUNCT__ 68d359177SBarry Smith #define __FUNCT__ "SNESComputeJacobianDefaultColor" 791627157SBarry Smith /*@C 88d359177SBarry Smith SNESComputeJacobianDefaultColor - Computes the Jacobian using 9b4fc646aSLois Curfman McInnes finite differences and coloring to exploit matrix sparsity. 1091627157SBarry Smith 11fee21e36SBarry Smith Collective on SNES 12fee21e36SBarry Smith 13c7afd0dbSLois Curfman McInnes Input Parameters: 14c7afd0dbSLois Curfman McInnes + snes - nonlinear solver object 15c7afd0dbSLois Curfman McInnes . x1 - location at which to evaluate Jacobian 16*7fb41025SPeter Brune - ctx - MatFDColoring context or NULL 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 25*7fb41025SPeter Brune .notes: If the coloring is not provided through the context, this will first try to get the 26*7fb41025SPeter Brune coloring from the DM. If the DM type has no coloring routine, then it will try to 27*7fb41025SPeter Brune get the coloring from the matrix. This requires that the matrix have nonzero entries 28*7fb41025SPeter Brune precomputed. This is discouraged, as MatGetColoring() is not parallel. 29b0ae01b7SPeter Brune 30b4fc646aSLois Curfman McInnes .keywords: SNES, finite differences, Jacobian, coloring, sparse 3191627157SBarry Smith 328d359177SBarry Smith .seealso: SNESSetJacobian(), SNESTestJacobian(), SNESComputeJacobianDefault() 33ab637aeaSJed Brown MatFDColoringCreate(), MatFDColoringSetFunction() 34cb5b572fSBarry Smith 3591627157SBarry Smith @*/ 3695d750ceSBarry Smith 378d359177SBarry Smith PetscErrorCode SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 3891627157SBarry Smith { 39*7fb41025SPeter Brune MatFDColoring color = (MatFDColoring)ctx; 40dfbe8321SBarry Smith PetscErrorCode ierr; 414e269d77SPeter Brune DM dm; 424e269d77SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 434e269d77SPeter Brune Vec F; 444e269d77SPeter Brune void *funcctx; 454e269d77SPeter Brune ISColoring iscoloring; 46b0ae01b7SPeter Brune PetscBool hascolor; 47dff777c9SBarry Smith 483a40ed3dSBarry Smith PetscFunctionBegin; 49*7fb41025SPeter Brune if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6); 50*7fb41025SPeter Brune else {ierr = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);} 5192abec31SBarry Smith *flag = SAME_NONZERO_PATTERN; 5222d28d08SBarry Smith ierr = SNESGetFunction(snes,&F,&func,&funcctx);CHKERRQ(ierr); 534e269d77SPeter Brune if (!color) { 544e269d77SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 55b0ae01b7SPeter Brune ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); 56b0ae01b7SPeter Brune if (hascolor) { 574e269d77SPeter Brune ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); 584e269d77SPeter Brune ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr); 594e269d77SPeter Brune ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 604e269d77SPeter Brune ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 614e269d77SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 62b0ae01b7SPeter Brune } else { 63b0ae01b7SPeter Brune ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 64b0ae01b7SPeter Brune ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr); 650171d955SPeter Brune ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 66b0ae01b7SPeter Brune ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr); 67b0ae01b7SPeter Brune ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 68b0ae01b7SPeter Brune } 694e269d77SPeter Brune ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); 704108615fSPeter Brune ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); 714a9d489dSBarry Smith } 7295862db2SPeter Brune 7395862db2SPeter Brune /* F is only usable if there is no RHS on the SNES */ 7495862db2SPeter Brune if (!snes->vec_rhs) { 75432bb422SPeter Brune ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); 7695862db2SPeter Brune } 77005c665bSBarry Smith ierr = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr); 7832dfb669SBarry Smith if (*J != *B) { 79194405b3SBarry Smith ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 80194405b3SBarry Smith ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 81194405b3SBarry Smith } 823a40ed3dSBarry Smith PetscFunctionReturn(0); 8391627157SBarry Smith } 84