137eeb815SJakub Kruzik 237eeb815SJakub Kruzik /* -------------------------------------------------------------------- 337eeb815SJakub Kruzik 437eeb815SJakub Kruzik This file implements a Deflation preconditioner in PETSc as part of PC. 537eeb815SJakub Kruzik You can use this as a starting point for implementing your own 637eeb815SJakub Kruzik preconditioner that is not provided with PETSc. (You might also consider 737eeb815SJakub Kruzik just using PCSHELL) 837eeb815SJakub Kruzik 937eeb815SJakub Kruzik The following basic routines are required for each preconditioner. 1037eeb815SJakub Kruzik PCCreate_XXX() - Creates a preconditioner context 1137eeb815SJakub Kruzik PCSetFromOptions_XXX() - Sets runtime options 1237eeb815SJakub Kruzik PCApply_XXX() - Applies the preconditioner 1337eeb815SJakub Kruzik PCDestroy_XXX() - Destroys the preconditioner context 1437eeb815SJakub Kruzik where the suffix "_XXX" denotes a particular implementation, in 1537eeb815SJakub Kruzik this case we use _Deflation (e.g., PCCreate_Deflation, PCApply_Deflation). 1637eeb815SJakub Kruzik These routines are actually called via the common user interface 1737eeb815SJakub Kruzik routines PCCreate(), PCSetFromOptions(), PCApply(), and PCDestroy(), 1837eeb815SJakub Kruzik so the application code interface remains identical for all 1937eeb815SJakub Kruzik preconditioners. 2037eeb815SJakub Kruzik 2137eeb815SJakub Kruzik Another key routine is: 2237eeb815SJakub Kruzik PCSetUp_XXX() - Prepares for the use of a preconditioner 2337eeb815SJakub Kruzik by setting data structures and options. The interface routine PCSetUp() 2437eeb815SJakub Kruzik is not usually called directly by the user, but instead is called by 2537eeb815SJakub Kruzik PCApply() if necessary. 2637eeb815SJakub Kruzik 2737eeb815SJakub Kruzik Additional basic routines are: 2837eeb815SJakub Kruzik PCView_XXX() - Prints details of runtime options that 2937eeb815SJakub Kruzik have actually been used. 3037eeb815SJakub Kruzik These are called by application codes via the interface routines 3137eeb815SJakub Kruzik PCView(). 3237eeb815SJakub Kruzik 3337eeb815SJakub Kruzik The various types of solvers (preconditioners, Krylov subspace methods, 3437eeb815SJakub Kruzik nonlinear solvers, timesteppers) are all organized similarly, so the 3537eeb815SJakub Kruzik above description applies to these categories also. One exception is 3637eeb815SJakub Kruzik that the analogues of PCApply() for these components are KSPSolve(), 3737eeb815SJakub Kruzik SNESSolve(), and TSSolve(). 3837eeb815SJakub Kruzik 3937eeb815SJakub Kruzik Additional optional functionality unique to preconditioners is left and 4037eeb815SJakub Kruzik right symmetric preconditioner application via PCApplySymmetricLeft() 4137eeb815SJakub Kruzik and PCApplySymmetricRight(). The Deflation implementation is 4237eeb815SJakub Kruzik PCApplySymmetricLeftOrRight_Deflation(). 4337eeb815SJakub Kruzik 4437eeb815SJakub Kruzik -------------------------------------------------------------------- */ 4537eeb815SJakub Kruzik 4637eeb815SJakub Kruzik /* 4737eeb815SJakub Kruzik Include files needed for the Deflation preconditioner: 4837eeb815SJakub Kruzik pcimpl.h - private include file intended for use by all preconditioners 4937eeb815SJakub Kruzik */ 5037eeb815SJakub Kruzik 51292e2e67SJakub Kruzik #include <../src/ksp/pc/impls/deflation/deflation.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 5237eeb815SJakub Kruzik 538513960bSJakub Kruzik const char *const PCDeflationSpaceTypes[] = { 548513960bSJakub Kruzik "haar", 558513960bSJakub Kruzik "jacket-haar", 568513960bSJakub Kruzik "db2", 578513960bSJakub Kruzik "db4", 588513960bSJakub Kruzik "db8", 598513960bSJakub Kruzik "db16", 608513960bSJakub Kruzik "biorth22", 618513960bSJakub Kruzik "meyer", 628513960bSJakub Kruzik "aggregation", 638513960bSJakub Kruzik "slepc", 648513960bSJakub Kruzik "slepc-cheap", 658513960bSJakub Kruzik "user", 668513960bSJakub Kruzik "DdefSpaceType", 678513960bSJakub Kruzik "Ddef_SPACE_", 688513960bSJakub Kruzik 0 698513960bSJakub Kruzik }; 708513960bSJakub Kruzik 718513960bSJakub Kruzik 72e662bc50SJakub Kruzik static PetscErrorCode PCDeflationSetSpace_Deflation(PC pc,Mat W,PetscBool transpose) 73e662bc50SJakub Kruzik { 74e662bc50SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 75e662bc50SJakub Kruzik PetscErrorCode ierr; 76e662bc50SJakub Kruzik 77e662bc50SJakub Kruzik PetscFunctionBegin; 78e662bc50SJakub Kruzik if (transpose) { 79e662bc50SJakub Kruzik def->Wt = W; 80e662bc50SJakub Kruzik def->W = NULL; 81e662bc50SJakub Kruzik } else { 82e662bc50SJakub Kruzik def->W = W; 83e662bc50SJakub Kruzik } 84e662bc50SJakub Kruzik ierr = PetscObjectReference((PetscObject)W);CHKERRQ(ierr); 85e662bc50SJakub Kruzik PetscFunctionReturn(0); 86e662bc50SJakub Kruzik } 87e662bc50SJakub Kruzik 88e662bc50SJakub Kruzik /* TODO create PCDeflationSetSpaceTranspose? */ 89e662bc50SJakub Kruzik /*@ 90e662bc50SJakub Kruzik PCDeflationSetSpace - Set deflation space matrix (or its transpose). 91e662bc50SJakub Kruzik 92e662bc50SJakub Kruzik Logically Collective on PC 93e662bc50SJakub Kruzik 94e662bc50SJakub Kruzik Input Parameters: 95e662bc50SJakub Kruzik + pc - the preconditioner context 96e662bc50SJakub Kruzik . W - deflation matrix 97e662bc50SJakub Kruzik - tranpose - indicates that W is an explicit transpose of the deflation matrix 98e662bc50SJakub Kruzik 99e662bc50SJakub Kruzik Level: intermediate 100e662bc50SJakub Kruzik 101e662bc50SJakub Kruzik .seealso: PCDEFLATION 102e662bc50SJakub Kruzik @*/ 103e662bc50SJakub Kruzik PetscErrorCode PCDeflationSetSpace(PC pc,Mat W,PetscBool transpose) 104e662bc50SJakub Kruzik { 105e662bc50SJakub Kruzik PetscErrorCode ierr; 106e662bc50SJakub Kruzik 107e662bc50SJakub Kruzik PetscFunctionBegin; 108e662bc50SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 109e662bc50SJakub Kruzik PetscValidHeaderSpecific(W,MAT_CLASSID,2); 110e662bc50SJakub Kruzik PetscValidLogicalCollectiveBool(pc,transpose,3); 111e662bc50SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetSpace_C",(PC,Mat,PetscBool),(pc,W,transpose));CHKERRQ(ierr); 112e662bc50SJakub Kruzik PetscFunctionReturn(0); 113e662bc50SJakub Kruzik } 114e662bc50SJakub Kruzik 115*e924b002SJakub Kruzik static PetscErrorCode PCDeflationSetCoarseMat_Deflation(PC pc,Mat mat) 116*e924b002SJakub Kruzik { 117*e924b002SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 118*e924b002SJakub Kruzik PetscErrorCode ierr; 119*e924b002SJakub Kruzik 120*e924b002SJakub Kruzik PetscFunctionBegin; 121*e924b002SJakub Kruzik ierr = MatDestroy(&def->WtAW);CHKERRQ(ierr); 122*e924b002SJakub Kruzik def->WtAW = mat; 123*e924b002SJakub Kruzik ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 124*e924b002SJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtAW);CHKERRQ(ierr); 125*e924b002SJakub Kruzik PetscFunctionReturn(0); 126*e924b002SJakub Kruzik } 127*e924b002SJakub Kruzik 128*e924b002SJakub Kruzik /*@ 129*e924b002SJakub Kruzik PCDeflationSetCoarseMat - Set coarse problem Mat. 130*e924b002SJakub Kruzik 131*e924b002SJakub Kruzik Not Collective 132*e924b002SJakub Kruzik 133*e924b002SJakub Kruzik Input Parameters: 134*e924b002SJakub Kruzik + pc - preconditioner context 135*e924b002SJakub Kruzik - mat - coarse problem mat 136*e924b002SJakub Kruzik 137*e924b002SJakub Kruzik Level: developer 138*e924b002SJakub Kruzik 139*e924b002SJakub Kruzik .seealso: PCDEFLATION 140*e924b002SJakub Kruzik @*/ 141*e924b002SJakub Kruzik PetscErrorCode PCDeflationSetCoarseMat(PC pc,Mat mat) 142*e924b002SJakub Kruzik { 143*e924b002SJakub Kruzik PetscErrorCode ierr; 144*e924b002SJakub Kruzik 145*e924b002SJakub Kruzik PetscFunctionBegin; 146*e924b002SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 147*e924b002SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 148*e924b002SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetCoarseMat_C",(PC,Mat),(pc,mat));CHKERRQ(ierr); 149*e924b002SJakub Kruzik PetscFunctionReturn(0); 150*e924b002SJakub Kruzik } 151*e924b002SJakub Kruzik 1525c0c31c5SJakub Kruzik static PetscErrorCode PCDeflationSetLvl_Deflation(PC pc,PetscInt current,PetscInt max) 1535c0c31c5SJakub Kruzik { 1545c0c31c5SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 1555c0c31c5SJakub Kruzik 1565c0c31c5SJakub Kruzik PetscFunctionBegin; 15781e2347eSJakub Kruzik if (current) def->nestedlvl = current; 1585c0c31c5SJakub Kruzik def->maxnestedlvl = max; 1595c0c31c5SJakub Kruzik PetscFunctionReturn(0); 1605c0c31c5SJakub Kruzik } 1615c0c31c5SJakub Kruzik 1625c0c31c5SJakub Kruzik /*@ 1635c0c31c5SJakub Kruzik PCDeflationSetMaxLvl - Set maximum level of deflation. 1645c0c31c5SJakub Kruzik 1655c0c31c5SJakub Kruzik Logically Collective on PC 1665c0c31c5SJakub Kruzik 1675c0c31c5SJakub Kruzik Input Parameters: 1685c0c31c5SJakub Kruzik + pc - the preconditioner context 16922b0793eSJakub Kruzik - max - maximum deflation level 1705c0c31c5SJakub Kruzik 1715c0c31c5SJakub Kruzik Level: intermediate 1725c0c31c5SJakub Kruzik 1735c0c31c5SJakub Kruzik .seealso: PCDEFLATION 1745c0c31c5SJakub Kruzik @*/ 1755c0c31c5SJakub Kruzik PetscErrorCode PCDeflationSetMaxLvl(PC pc,PetscInt max) 1765c0c31c5SJakub Kruzik { 1775c0c31c5SJakub Kruzik PetscErrorCode ierr; 1785c0c31c5SJakub Kruzik 1795c0c31c5SJakub Kruzik PetscFunctionBegin; 18022b0793eSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1815c0c31c5SJakub Kruzik PetscValidLogicalCollectiveInt(pc,max,2); 1825c0c31c5SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetLvl_C",(PC,PetscInt,PetscInt),(pc,0,max));CHKERRQ(ierr); 1835c0c31c5SJakub Kruzik PetscFunctionReturn(0); 1845c0c31c5SJakub Kruzik } 185e662bc50SJakub Kruzik 186268c6673SJakub Kruzik static PetscErrorCode PCDeflationGetPC_Deflation(PC pc,PC *apc) 187268c6673SJakub Kruzik { 188268c6673SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 189268c6673SJakub Kruzik 190268c6673SJakub Kruzik PetscFunctionBegin; 191268c6673SJakub Kruzik *apc = def->pc; 192268c6673SJakub Kruzik PetscFunctionReturn(0); 193268c6673SJakub Kruzik } 194268c6673SJakub Kruzik 195268c6673SJakub Kruzik /*@ 196268c6673SJakub Kruzik PCDeflationGetPC - Returns a pointer to additional preconditioner. 197268c6673SJakub Kruzik 198268c6673SJakub Kruzik Not Collective 199268c6673SJakub Kruzik 200268c6673SJakub Kruzik Input Parameters: 201268c6673SJakub Kruzik . pc - the preconditioner context 202268c6673SJakub Kruzik 203268c6673SJakub Kruzik Output Parameter: 204268c6673SJakub Kruzik . apc - additional preconditioner 205268c6673SJakub Kruzik 206268c6673SJakub Kruzik Level: advanced 207268c6673SJakub Kruzik 208268c6673SJakub Kruzik .seealso: PCDeflationSetPC(), PCDEFLATION 209268c6673SJakub Kruzik @*/ 210268c6673SJakub Kruzik PetscErrorCode PCDeflationGetPC(PC pc,PC *apc) 211268c6673SJakub Kruzik { 212268c6673SJakub Kruzik PetscErrorCode ierr; 213268c6673SJakub Kruzik 214268c6673SJakub Kruzik PetscFunctionBegin; 215268c6673SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 216268c6673SJakub Kruzik PetscValidPointer(pc,2); 217268c6673SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationGetPC_C",(PC,PC*),(pc,apc));CHKERRQ(ierr); 218268c6673SJakub Kruzik PetscFunctionReturn(0); 219268c6673SJakub Kruzik } 220268c6673SJakub Kruzik 22122b0793eSJakub Kruzik static PetscErrorCode PCDeflationSetPC_Deflation(PC pc,PC apc) 22222b0793eSJakub Kruzik { 22322b0793eSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 22422b0793eSJakub Kruzik PetscErrorCode ierr; 22522b0793eSJakub Kruzik 22622b0793eSJakub Kruzik PetscFunctionBegin; 22722b0793eSJakub Kruzik ierr = PCDestroy(&def->pc);CHKERRQ(ierr); 22822b0793eSJakub Kruzik def->pc = apc; 22922b0793eSJakub Kruzik ierr = PetscObjectReference((PetscObject)apc);CHKERRQ(ierr); 23022b0793eSJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->pc);CHKERRQ(ierr); 23122b0793eSJakub Kruzik PetscFunctionReturn(0); 23222b0793eSJakub Kruzik } 23322b0793eSJakub Kruzik 23422b0793eSJakub Kruzik /*@ 23522b0793eSJakub Kruzik PCDeflationSetPC - Set additional preconditioner. 23622b0793eSJakub Kruzik 237268c6673SJakub Kruzik Collective on PC 23822b0793eSJakub Kruzik 23922b0793eSJakub Kruzik Input Parameters: 24022b0793eSJakub Kruzik + pc - the preconditioner context 24122b0793eSJakub Kruzik - apc - additional preconditioner 24222b0793eSJakub Kruzik 243268c6673SJakub Kruzik Level: developer 24422b0793eSJakub Kruzik 245268c6673SJakub Kruzik .seealso: PCDeflationGetPC(), PCDEFLATION 24622b0793eSJakub Kruzik @*/ 24722b0793eSJakub Kruzik PetscErrorCode PCDeflationSetPC(PC pc,PC apc) 24822b0793eSJakub Kruzik { 24922b0793eSJakub Kruzik PetscErrorCode ierr; 25022b0793eSJakub Kruzik 25122b0793eSJakub Kruzik PetscFunctionBegin; 25222b0793eSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 25322b0793eSJakub Kruzik PetscValidHeaderSpecific(apc,PC_CLASSID,2); 25422b0793eSJakub Kruzik PetscCheckSameComm(pc,1,apc,2); 25522b0793eSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetPC_C",(PC,PC),(pc,apc));CHKERRQ(ierr); 25622b0793eSJakub Kruzik PetscFunctionReturn(0); 25722b0793eSJakub Kruzik } 25822b0793eSJakub Kruzik 2594a99276eSJakub Kruzik static PetscErrorCode PCDeflationGetCoarseKSP_Deflation(PC pc,KSP *ksp) 2604a99276eSJakub Kruzik { 2614a99276eSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 2624a99276eSJakub Kruzik 2634a99276eSJakub Kruzik PetscFunctionBegin; 2644a99276eSJakub Kruzik *ksp = def->WtAWinv; 2654a99276eSJakub Kruzik PetscFunctionReturn(0); 2664a99276eSJakub Kruzik } 2674a99276eSJakub Kruzik 2684a99276eSJakub Kruzik /*@ 2694a99276eSJakub Kruzik PCDeflationGetCoarseKSP - Returns a pointer to the coarse problem KSP. 2704a99276eSJakub Kruzik 2714a99276eSJakub Kruzik Not Collective 2724a99276eSJakub Kruzik 2734a99276eSJakub Kruzik Input Parameters: 2744a99276eSJakub Kruzik . pc - preconditioner context 2754a99276eSJakub Kruzik 2764a99276eSJakub Kruzik Output Parameter: 2774a99276eSJakub Kruzik . ksp - coarse problem KSP context 2784a99276eSJakub Kruzik 2794a99276eSJakub Kruzik Level: developer 2804a99276eSJakub Kruzik 281f3eaa4f0SJakub Kruzik .seealso: PCDeflationSetCoarseKSP(), PCDEFLATION 2824a99276eSJakub Kruzik @*/ 2834a99276eSJakub Kruzik PetscErrorCode PCDeflationGetCoarseKSP(PC pc,KSP *ksp) 2844a99276eSJakub Kruzik { 2854a99276eSJakub Kruzik PetscErrorCode ierr; 2864a99276eSJakub Kruzik 2874a99276eSJakub Kruzik PetscFunctionBegin; 2884a99276eSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2894a99276eSJakub Kruzik PetscValidPointer(ksp,2); 2904a99276eSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationGetCoarseKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr); 2914a99276eSJakub Kruzik PetscFunctionReturn(0); 2924a99276eSJakub Kruzik } 2934a99276eSJakub Kruzik 294f3eaa4f0SJakub Kruzik static PetscErrorCode PCDeflationSetCoarseKSP_Deflation(PC pc,KSP ksp) 295f3eaa4f0SJakub Kruzik { 296f3eaa4f0SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 297f3eaa4f0SJakub Kruzik PetscErrorCode ierr; 298f3eaa4f0SJakub Kruzik 299f3eaa4f0SJakub Kruzik PetscFunctionBegin; 300f3eaa4f0SJakub Kruzik ierr = KSPDestroy(&def->WtAWinv);CHKERRQ(ierr); 301f3eaa4f0SJakub Kruzik def->WtAWinv = ksp; 302f3eaa4f0SJakub Kruzik ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 303f3eaa4f0SJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtAWinv);CHKERRQ(ierr); 304f3eaa4f0SJakub Kruzik PetscFunctionReturn(0); 305f3eaa4f0SJakub Kruzik } 306f3eaa4f0SJakub Kruzik 307f3eaa4f0SJakub Kruzik /*@ 308f3eaa4f0SJakub Kruzik PCDeflationSetCoarseKSP - Set coarse problem KSP. 309f3eaa4f0SJakub Kruzik 310f3eaa4f0SJakub Kruzik Collective on PC 311f3eaa4f0SJakub Kruzik 312f3eaa4f0SJakub Kruzik Input Parameters: 313f3eaa4f0SJakub Kruzik + pc - preconditioner context 314f3eaa4f0SJakub Kruzik - ksp - coarse problem KSP context 315f3eaa4f0SJakub Kruzik 316f3eaa4f0SJakub Kruzik Level: developer 317f3eaa4f0SJakub Kruzik 318f3eaa4f0SJakub Kruzik .seealso: PCDeflationGetCoarseKSP(), PCDEFLATION 319f3eaa4f0SJakub Kruzik @*/ 320f3eaa4f0SJakub Kruzik PetscErrorCode PCDeflationSetCoarseKSP(PC pc,KSP ksp) 321f3eaa4f0SJakub Kruzik { 322f3eaa4f0SJakub Kruzik PetscErrorCode ierr; 323f3eaa4f0SJakub Kruzik 324f3eaa4f0SJakub Kruzik PetscFunctionBegin; 325f3eaa4f0SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 326f3eaa4f0SJakub Kruzik PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 327f3eaa4f0SJakub Kruzik PetscCheckSameComm(pc,1,ksp,2); 328f3eaa4f0SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetCoarseKSP_C",(PC,KSP),(pc,ksp));CHKERRQ(ierr); 329f3eaa4f0SJakub Kruzik PetscFunctionReturn(0); 330f3eaa4f0SJakub Kruzik } 331f3eaa4f0SJakub Kruzik 33237eeb815SJakub Kruzik /* 333b27c8092SJakub Kruzik x <- x + W*(W'*A*W)^{-1}*W'*r = x + Q*r 334b27c8092SJakub Kruzik */ 335b27c8092SJakub Kruzik static PetscErrorCode PCPreSolve_Deflation(PC pc,KSP ksp,Vec b, Vec x) 336b27c8092SJakub Kruzik { 337b27c8092SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 338b27c8092SJakub Kruzik Mat A; 339b27c8092SJakub Kruzik Vec r,w1,w2; 340b27c8092SJakub Kruzik PetscBool nonzero; 341b27c8092SJakub Kruzik PetscErrorCode ierr; 34237eeb815SJakub Kruzik 343b27c8092SJakub Kruzik PetscFunctionBegin; 344b27c8092SJakub Kruzik w1 = def->workcoarse[0]; 345b27c8092SJakub Kruzik w2 = def->workcoarse[1]; 346b27c8092SJakub Kruzik r = def->work; 347b27c8092SJakub Kruzik ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr); 34837eeb815SJakub Kruzik 349b27c8092SJakub Kruzik ierr = KSPGetInitialGuessNonzero(ksp,&nonzero);CHKERRQ(ierr); 350b27c8092SJakub Kruzik ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 351b27c8092SJakub Kruzik if (nonzero) { 352b27c8092SJakub Kruzik ierr = MatMult(A,x,r);CHKERRQ(ierr); /* r <- b - Ax */ 353b27c8092SJakub Kruzik ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 354b27c8092SJakub Kruzik } else { 355b27c8092SJakub Kruzik ierr = VecCopy(b,r);CHKERRQ(ierr); /* r <- b (x is 0) */ 356b27c8092SJakub Kruzik } 357b27c8092SJakub Kruzik 358b27c8092SJakub Kruzik ierr = MatMultTranspose(def->W,r,w1);CHKERRQ(ierr); /* w1 <- W'*r */ 359b27c8092SJakub Kruzik ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr); /* w2 <- (W'*A*W)^{-1}*w1 */ 360b27c8092SJakub Kruzik ierr = MatMult(def->W,w2,r);CHKERRQ(ierr); /* r <- W*w2 */ 361b27c8092SJakub Kruzik ierr = VecAYPX(x,1.0,r);CHKERRQ(ierr); 362b27c8092SJakub Kruzik PetscFunctionReturn(0); 363b27c8092SJakub Kruzik } 36437eeb815SJakub Kruzik 365f8bf229cSJakub Kruzik /* 366f8bf229cSJakub Kruzik if (def->correct) { 367ae029463SJakub Kruzik z <- M^{-1}r - W*(W'*A*W)^{-1}*(W'*A*M^{-1}r - l*W'*r) = (P*M^{-1} + l*Q)*r 368f8bf229cSJakub Kruzik } else { 369ae029463SJakub Kruzik z <- M^{-1}*r - W*(W'*A*W)^{-1}*W'*A*M{-1}*r = P*M^{-1}*r 370f8bf229cSJakub Kruzik } 37137eeb815SJakub Kruzik */ 372f8bf229cSJakub Kruzik static PetscErrorCode PCApply_Deflation(PC pc,Vec r,Vec z) 373f8bf229cSJakub Kruzik { 374f8bf229cSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 375f8bf229cSJakub Kruzik Mat A; 376f8bf229cSJakub Kruzik Vec u,w1,w2; 377f8bf229cSJakub Kruzik PetscErrorCode ierr; 378f8bf229cSJakub Kruzik 379f8bf229cSJakub Kruzik PetscFunctionBegin; 380f8bf229cSJakub Kruzik w1 = def->workcoarse[0]; 381f8bf229cSJakub Kruzik w2 = def->workcoarse[1]; 382f8bf229cSJakub Kruzik u = def->work; 383f8bf229cSJakub Kruzik ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr); 384f8bf229cSJakub Kruzik 385ae029463SJakub Kruzik ierr = PCApply(def->pc,r,z);CHKERRQ(ierr); /* z <- M^{-1}*r */ 38622b0793eSJakub Kruzik if (!def->init) { 387ae029463SJakub Kruzik ierr = MatMult(def->WtA,z,w1);CHKERRQ(ierr); /* w1 <- W'*A*z */ 388f8bf229cSJakub Kruzik if (def->correct) { 389ae029463SJakub Kruzik if (def->Wt) { 390ae029463SJakub Kruzik ierr = MatMult(def->Wt,r,w2);CHKERRQ(ierr); /* w2 <- W'*r */ 391ae029463SJakub Kruzik } else { 392ae029463SJakub Kruzik ierr = MatMultTranspose(def->W,r,w2);CHKERRQ(ierr); /* w2 <- W'*r */ 393f8bf229cSJakub Kruzik } 394ae029463SJakub Kruzik ierr = VecAXPY(w1,-1.0*def->correctfact,w2);CHKERRQ(ierr); /* w1 <- w1 - l*w2 */ 395f8bf229cSJakub Kruzik } 396f8bf229cSJakub Kruzik ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr); /* w2 <- (W'*A*W)^{-1}*w1 */ 397f8bf229cSJakub Kruzik ierr = MatMult(def->W,w2,u);CHKERRQ(ierr); /* u <- W*w2 */ 39822b0793eSJakub Kruzik ierr = VecAXPY(z,-1.0,u);CHKERRQ(ierr); /* z <- z - u */ 39922b0793eSJakub Kruzik } 400f8bf229cSJakub Kruzik PetscFunctionReturn(0); 401f8bf229cSJakub Kruzik } 402f8bf229cSJakub Kruzik 40337eeb815SJakub Kruzik static PetscErrorCode PCSetUp_Deflation(PC pc) 40437eeb815SJakub Kruzik { 405409a357bSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 406409a357bSJakub Kruzik KSP innerksp; 407409a357bSJakub Kruzik PC pcinner; 408409a357bSJakub Kruzik Mat Amat,nextDef=NULL,*mats; 409409a357bSJakub Kruzik PetscInt i,m,red,size,commsize; 410409a357bSJakub Kruzik PetscBool match,flgspd,transp=PETSC_FALSE; 411409a357bSJakub Kruzik MatCompositeType ctype; 412409a357bSJakub Kruzik MPI_Comm comm; 413409a357bSJakub Kruzik const char *prefix; 41437eeb815SJakub Kruzik PetscErrorCode ierr; 41537eeb815SJakub Kruzik 41637eeb815SJakub Kruzik PetscFunctionBegin; 417409a357bSJakub Kruzik if (pc->setupcalled) PetscFunctionReturn(0); 418409a357bSJakub Kruzik ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 419f8bf229cSJakub Kruzik ierr = PCGetOperators(pc,NULL,&Amat);CHKERRQ(ierr); 420f8bf229cSJakub Kruzik 421f8bf229cSJakub Kruzik /* compute a deflation space */ 422409a357bSJakub Kruzik if (def->W || def->Wt) { 423409a357bSJakub Kruzik def->spacetype = PC_DEFLATION_SPACE_USER; 424409a357bSJakub Kruzik } else { 425e53e0a0dSJakub Kruzik ierr = PCDeflationComputeSpace(pc);CHKERRQ(ierr); 42637eeb815SJakub Kruzik } 42737eeb815SJakub Kruzik 428409a357bSJakub Kruzik /* nested deflation */ 429409a357bSJakub Kruzik if (def->W) { 430409a357bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)def->W,MATCOMPOSITE,&match);CHKERRQ(ierr); 431409a357bSJakub Kruzik if (match) { 432409a357bSJakub Kruzik ierr = MatCompositeGetType(def->W,&ctype);CHKERRQ(ierr); 433409a357bSJakub Kruzik ierr = MatCompositeGetNumberMat(def->W,&size);CHKERRQ(ierr); 43437eeb815SJakub Kruzik } 435409a357bSJakub Kruzik } else { 436409a357bSJakub Kruzik ierr = MatCreateTranspose(def->Wt,&def->W);CHKERRQ(ierr); 437409a357bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)def->Wt,MATCOMPOSITE,&match);CHKERRQ(ierr); 438409a357bSJakub Kruzik if (match) { 439409a357bSJakub Kruzik ierr = MatCompositeGetType(def->Wt,&ctype);CHKERRQ(ierr); 440409a357bSJakub Kruzik ierr = MatCompositeGetNumberMat(def->Wt,&size);CHKERRQ(ierr); 441409a357bSJakub Kruzik } 442409a357bSJakub Kruzik transp = PETSC_TRUE; 443409a357bSJakub Kruzik } 444409a357bSJakub Kruzik if (match && ctype == MAT_COMPOSITE_MULTIPLICATIVE) { 445409a357bSJakub Kruzik if (!transp) { 44628da0170SJakub Kruzik if (def->nestedlvl < def->maxnestedlvl) { 44728da0170SJakub Kruzik ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr); 448409a357bSJakub Kruzik for (i=0; i<size; i++) { 449409a357bSJakub Kruzik ierr = MatCompositeGetMat(def->W,i,&mats[i]);CHKERRQ(ierr); 450409a357bSJakub Kruzik } 451409a357bSJakub Kruzik size -= 1; 452409a357bSJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 453409a357bSJakub Kruzik def->W = mats[size]; 454409a357bSJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[size]);CHKERRQ(ierr); 455409a357bSJakub Kruzik if (size > 1) { 456409a357bSJakub Kruzik ierr = MatCreateComposite(comm,size,mats,&nextDef);CHKERRQ(ierr); 457409a357bSJakub Kruzik ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); 458409a357bSJakub Kruzik } else { 459409a357bSJakub Kruzik nextDef = mats[0]; 460409a357bSJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr); 461409a357bSJakub Kruzik } 46228da0170SJakub Kruzik ierr = PetscFree(mats);CHKERRQ(ierr); 463409a357bSJakub Kruzik } else { 464409a357bSJakub Kruzik /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */ 465409a357bSJakub Kruzik ierr = MatCompositeMerge(def->W);CHKERRQ(ierr); 466409a357bSJakub Kruzik } 46728da0170SJakub Kruzik } else { 46828da0170SJakub Kruzik if (def->nestedlvl < def->maxnestedlvl) { 46928da0170SJakub Kruzik ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr); 47028da0170SJakub Kruzik for (i=0; i<size; i++) { 47128da0170SJakub Kruzik ierr = MatCompositeGetMat(def->Wt,i,&mats[i]);CHKERRQ(ierr); 47228da0170SJakub Kruzik } 47328da0170SJakub Kruzik size -= 1; 47428da0170SJakub Kruzik ierr = MatDestroy(&def->Wt);CHKERRQ(ierr); 47528da0170SJakub Kruzik def->Wt = mats[0]; 47628da0170SJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr); 47728da0170SJakub Kruzik if (size > 1) { 47828da0170SJakub Kruzik ierr = MatCreateComposite(comm,size,&mats[1],&nextDef);CHKERRQ(ierr); 47928da0170SJakub Kruzik ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); 48028da0170SJakub Kruzik } else { 48128da0170SJakub Kruzik nextDef = mats[1]; 48228da0170SJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[1]);CHKERRQ(ierr); 483409a357bSJakub Kruzik } 484409a357bSJakub Kruzik ierr = PetscFree(mats);CHKERRQ(ierr); 48528da0170SJakub Kruzik } else { 48628da0170SJakub Kruzik /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */ 48728da0170SJakub Kruzik ierr = MatCompositeMerge(def->Wt);CHKERRQ(ierr); 48828da0170SJakub Kruzik } 48928da0170SJakub Kruzik } 49028da0170SJakub Kruzik } 49128da0170SJakub Kruzik 49228da0170SJakub Kruzik if (transp) { 49328da0170SJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 49428da0170SJakub Kruzik ierr = MatTranspose(def->Wt,MAT_INITIAL_MATRIX,&def->W);CHKERRQ(ierr); 495409a357bSJakub Kruzik } 496409a357bSJakub Kruzik 49722b0793eSJakub Kruzik 49822b0793eSJakub Kruzik ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 49922b0793eSJakub Kruzik 500ae029463SJakub Kruzik /* assemble WtA */ 501ae029463SJakub Kruzik if (!def->WtA) { 502ae029463SJakub Kruzik if (def->Wt) { 503ae029463SJakub Kruzik ierr = MatMatMult(def->Wt,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr); 504ae029463SJakub Kruzik } else { 505ae029463SJakub Kruzik ierr = MatTransposeMatMult(def->W,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr); 506ae029463SJakub Kruzik } 507ae029463SJakub Kruzik } 508409a357bSJakub Kruzik /* setup coarse problem */ 509409a357bSJakub Kruzik if (!def->WtAWinv) { 51028da0170SJakub Kruzik ierr = MatGetSize(def->W,NULL,&m);CHKERRQ(ierr); 511409a357bSJakub Kruzik if (!def->WtAW) { 512ae029463SJakub Kruzik ierr = MatMatMult(def->WtA,def->W,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtAW);CHKERRQ(ierr); 513409a357bSJakub Kruzik /* TODO create MatInheritOption(Mat,MatOption) */ 514409a357bSJakub Kruzik ierr = MatGetOption(Amat,MAT_SPD,&flgspd);CHKERRQ(ierr); 515409a357bSJakub Kruzik ierr = MatSetOption(def->WtAW,MAT_SPD,flgspd);CHKERRQ(ierr); 516409a357bSJakub Kruzik #if defined(PETSC_USE_DEBUG) 517ae029463SJakub Kruzik /* Check columns of W are not in kernel of A */ 518409a357bSJakub Kruzik PetscReal *norms; 519409a357bSJakub Kruzik ierr = PetscMalloc1(m,&norms);CHKERRQ(ierr); 520409a357bSJakub Kruzik ierr = MatGetColumnNorms(def->WtAW,NORM_INFINITY,norms);CHKERRQ(ierr); 521409a357bSJakub Kruzik for (i=0; i<m; i++) { 522409a357bSJakub Kruzik if (norms[i] < 100*PETSC_MACHINE_EPSILON) { 523409a357bSJakub Kruzik SETERRQ1(comm,PETSC_ERR_SUP,"Column %D of W is in kernel of A.",i); 524409a357bSJakub Kruzik } 525409a357bSJakub Kruzik } 526409a357bSJakub Kruzik ierr = PetscFree(norms);CHKERRQ(ierr); 527409a357bSJakub Kruzik #endif 528409a357bSJakub Kruzik } else { 529409a357bSJakub Kruzik ierr = MatGetOption(def->WtAW,MAT_SPD,&flgspd);CHKERRQ(ierr); 530409a357bSJakub Kruzik } 531409a357bSJakub Kruzik /* TODO use MATINV */ 532409a357bSJakub Kruzik ierr = KSPCreate(comm,&def->WtAWinv);CHKERRQ(ierr); 533409a357bSJakub Kruzik ierr = KSPSetOperators(def->WtAWinv,def->WtAW,def->WtAW);CHKERRQ(ierr); 534409a357bSJakub Kruzik ierr = KSPGetPC(def->WtAWinv,&pcinner);CHKERRQ(ierr); 535557a2f7dSJakub Kruzik /* Setup KSP and PC */ 536557a2f7dSJakub Kruzik if (nextDef) { /* next level for multilevel deflation */ 537557a2f7dSJakub Kruzik innerksp = def->WtAWinv; 538557a2f7dSJakub Kruzik /* set default KSPtype */ 539557a2f7dSJakub Kruzik if (!def->ksptype) { 540557a2f7dSJakub Kruzik def->ksptype = KSPFGMRES; 541557a2f7dSJakub Kruzik if (flgspd) { /* SPD system */ 542557a2f7dSJakub Kruzik def->ksptype = KSPFCG; 543557a2f7dSJakub Kruzik } 544557a2f7dSJakub Kruzik } 545ae029463SJakub Kruzik ierr = KSPSetType(innerksp,def->ksptype);CHKERRQ(ierr); /* TODO iherit from KSP + tolerances */ 546557a2f7dSJakub Kruzik ierr = PCSetType(pcinner,PCDEFLATION);CHKERRQ(ierr); /* TODO create coarse preconditinoner M_c = WtMW ? */ 547557a2f7dSJakub Kruzik ierr = PCDeflationSetSpace(pcinner,nextDef,transp);CHKERRQ(ierr); 548557a2f7dSJakub Kruzik ierr = PCDeflationSetLvl_Deflation(pcinner,def->nestedlvl+1,def->maxnestedlvl);CHKERRQ(ierr); 549ae029463SJakub Kruzik /* inherit options */ 550557a2f7dSJakub Kruzik ((PC_Deflation*)(pcinner->data))->ksptype = def->ksptype; 551557a2f7dSJakub Kruzik ((PC_Deflation*)(pcinner->data))->correct = def->correct; 552557a2f7dSJakub Kruzik ierr = MatDestroy(&nextDef);CHKERRQ(ierr); 553557a2f7dSJakub Kruzik } else { /* the last level */ 554557a2f7dSJakub Kruzik ierr = KSPSetType(def->WtAWinv,KSPPREONLY);CHKERRQ(ierr); 555409a357bSJakub Kruzik ierr = PCSetType(pcinner,PCTELESCOPE);CHKERRQ(ierr); 556ac66f006SJakub Kruzik /* ugly hack to not have overwritten PCTELESCOPE */ 557ac66f006SJakub Kruzik if (prefix) { 558ac66f006SJakub Kruzik ierr = KSPSetOptionsPrefix(def->WtAWinv,prefix);CHKERRQ(ierr); 559ac66f006SJakub Kruzik } 56022b0793eSJakub Kruzik ierr = KSPAppendOptionsPrefix(def->WtAWinv,"tel_");CHKERRQ(ierr); 561ac66f006SJakub Kruzik ierr = PCSetFromOptions(pcinner);CHKERRQ(ierr); 562409a357bSJakub Kruzik /* Reduction factor choice */ 563409a357bSJakub Kruzik red = def->reductionfact; 564409a357bSJakub Kruzik if (red < 0) { 565409a357bSJakub Kruzik ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 566409a357bSJakub Kruzik red = ceil((float)commsize/ceil((float)m/commsize)); 567409a357bSJakub Kruzik ierr = PetscObjectTypeCompareAny((PetscObject)(def->WtAW),&match,MATSEQDENSE,MATMPIDENSE,MATDENSE,"");CHKERRQ(ierr); 568409a357bSJakub Kruzik if (match) red = commsize; 569409a357bSJakub Kruzik ierr = PetscInfo1(pc,"Auto choosing reduction factor %D\n",red);CHKERRQ(ierr); /* TODO add level? */ 570409a357bSJakub Kruzik } 571409a357bSJakub Kruzik ierr = PCTelescopeSetReductionFactor(pcinner,red);CHKERRQ(ierr); 572ac66f006SJakub Kruzik ierr = PCSetUp(pcinner);CHKERRQ(ierr); 573409a357bSJakub Kruzik ierr = PCTelescopeGetKSP(pcinner,&innerksp);CHKERRQ(ierr); 574ac66f006SJakub Kruzik if (innerksp) { 575409a357bSJakub Kruzik ierr = KSPGetPC(innerksp,&pcinner);CHKERRQ(ierr); 576409a357bSJakub Kruzik /* TODO Cholesky if flgspd? */ 577ac66f006SJakub Kruzik ierr = PCSetType(pcinner,PCLU);CHKERRQ(ierr); 578409a357bSJakub Kruzik //TODO remove explicit matSolverPackage 579409a357bSJakub Kruzik if (commsize == red) { 580ac66f006SJakub Kruzik ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU);CHKERRQ(ierr); 581409a357bSJakub Kruzik } else { 582ac66f006SJakub Kruzik ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU_DIST);CHKERRQ(ierr); 583409a357bSJakub Kruzik } 584409a357bSJakub Kruzik } 585557a2f7dSJakub Kruzik } 586557a2f7dSJakub Kruzik 587557a2f7dSJakub Kruzik if (innerksp) { 588409a357bSJakub Kruzik /* TODO use def_[lvl]_ if lvl > 0? */ 589409a357bSJakub Kruzik if (prefix) { 590409a357bSJakub Kruzik ierr = KSPSetOptionsPrefix(innerksp,prefix);CHKERRQ(ierr); 591409a357bSJakub Kruzik } 59222b0793eSJakub Kruzik ierr = KSPAppendOptionsPrefix(innerksp,"def_");CHKERRQ(ierr); 593557a2f7dSJakub Kruzik ierr = KSPSetFromOptions(innerksp);CHKERRQ(ierr); 594557a2f7dSJakub Kruzik ierr = KSPSetUp(innerksp);CHKERRQ(ierr); 595ac66f006SJakub Kruzik } 596409a357bSJakub Kruzik } 597557a2f7dSJakub Kruzik ierr = KSPSetFromOptions(def->WtAWinv);CHKERRQ(ierr); 598557a2f7dSJakub Kruzik ierr = KSPSetUp(def->WtAWinv);CHKERRQ(ierr); 599409a357bSJakub Kruzik 60022b0793eSJakub Kruzik if (!def->pc) { 60122b0793eSJakub Kruzik ierr = PCCreate(comm,&def->pc);CHKERRQ(ierr); 60222b0793eSJakub Kruzik ierr = PCSetOperators(def->pc,Amat,Amat);CHKERRQ(ierr); 60322b0793eSJakub Kruzik ierr = PCSetType(def->pc,PCNONE);CHKERRQ(ierr); 60422b0793eSJakub Kruzik if (prefix) { 60522b0793eSJakub Kruzik ierr = PCSetOptionsPrefix(def->pc,prefix);CHKERRQ(ierr); 60622b0793eSJakub Kruzik } 60722b0793eSJakub Kruzik ierr = PCAppendOptionsPrefix(def->pc,"def_pc_");CHKERRQ(ierr); 60822b0793eSJakub Kruzik ierr = PCSetFromOptions(def->pc);CHKERRQ(ierr); 60922b0793eSJakub Kruzik ierr = PCSetUp(def->pc);CHKERRQ(ierr); 61022b0793eSJakub Kruzik } 61122b0793eSJakub Kruzik 612f8bf229cSJakub Kruzik /* create work vecs */ 613f8bf229cSJakub Kruzik ierr = MatCreateVecs(Amat,NULL,&def->work);CHKERRQ(ierr); 614f8bf229cSJakub Kruzik ierr = KSPCreateVecs(def->WtAWinv,2,&def->workcoarse,0,NULL);CHKERRQ(ierr); 61537eeb815SJakub Kruzik PetscFunctionReturn(0); 61637eeb815SJakub Kruzik } 617b30d4775SJakub Kruzik 61837eeb815SJakub Kruzik static PetscErrorCode PCReset_Deflation(PC pc) 61937eeb815SJakub Kruzik { 620b30d4775SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 62137eeb815SJakub Kruzik PetscErrorCode ierr; 62237eeb815SJakub Kruzik 62337eeb815SJakub Kruzik PetscFunctionBegin; 624b30d4775SJakub Kruzik ierr = VecDestroy(&def->work);CHKERRQ(ierr); 625b30d4775SJakub Kruzik ierr = VecDestroyVecs(2,&def->workcoarse);CHKERRQ(ierr); 626b30d4775SJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 627b30d4775SJakub Kruzik ierr = MatDestroy(&def->Wt);CHKERRQ(ierr); 628ae029463SJakub Kruzik ierr = MatDestroy(&def->WtA);CHKERRQ(ierr); 629b30d4775SJakub Kruzik ierr = MatDestroy(&def->WtAW);CHKERRQ(ierr); 630b30d4775SJakub Kruzik ierr = KSPDestroy(&def->WtAWinv);CHKERRQ(ierr); 63122b0793eSJakub Kruzik ierr = PCDestroy(&def->pc);CHKERRQ(ierr); 63237eeb815SJakub Kruzik PetscFunctionReturn(0); 63337eeb815SJakub Kruzik } 63437eeb815SJakub Kruzik 63537eeb815SJakub Kruzik /* 63637eeb815SJakub Kruzik PCDestroy_Deflation - Destroys the private context for the Deflation preconditioner 63737eeb815SJakub Kruzik that was created with PCCreate_Deflation(). 63837eeb815SJakub Kruzik 63937eeb815SJakub Kruzik Input Parameter: 64037eeb815SJakub Kruzik . pc - the preconditioner context 64137eeb815SJakub Kruzik 64237eeb815SJakub Kruzik Application Interface Routine: PCDestroy() 64337eeb815SJakub Kruzik */ 64437eeb815SJakub Kruzik static PetscErrorCode PCDestroy_Deflation(PC pc) 64537eeb815SJakub Kruzik { 64637eeb815SJakub Kruzik PetscErrorCode ierr; 64737eeb815SJakub Kruzik 64837eeb815SJakub Kruzik PetscFunctionBegin; 64937eeb815SJakub Kruzik ierr = PCReset_Deflation(pc);CHKERRQ(ierr); 65037eeb815SJakub Kruzik ierr = PetscFree(pc->data);CHKERRQ(ierr); 65137eeb815SJakub Kruzik PetscFunctionReturn(0); 65237eeb815SJakub Kruzik } 65337eeb815SJakub Kruzik 6548513960bSJakub Kruzik static PetscErrorCode PCView_Deflation(PC pc,PetscViewer viewer) 6558513960bSJakub Kruzik { 6568513960bSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 6578513960bSJakub Kruzik PetscBool iascii; 6588513960bSJakub Kruzik PetscErrorCode ierr; 6598513960bSJakub Kruzik 6608513960bSJakub Kruzik PetscFunctionBegin; 6618513960bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 6628513960bSJakub Kruzik if (iascii) { 6638513960bSJakub Kruzik //if (cg->adaptiveconv) { 6648513960bSJakub Kruzik // ierr = PetscViewerASCIIPrintf(viewer," DCG: using adaptive precision for inner solve with C=%.1e\n",cg->adaptiveconst);CHKERRQ(ierr); 6658513960bSJakub Kruzik //} 6668513960bSJakub Kruzik if (def->correct) { 6678513960bSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer," Using CP correction\n");CHKERRQ(ierr); 6688513960bSJakub Kruzik } 6698513960bSJakub Kruzik if (!def->nestedlvl) { 6708513960bSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer," Deflation space type: %s\n",PCDeflationSpaceTypes[def->spacetype]);CHKERRQ(ierr); 6718513960bSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer," DCG %s\n",def->extendsp ? "extended" : "truncated");CHKERRQ(ierr); 6728513960bSJakub Kruzik } 6738513960bSJakub Kruzik 67422b0793eSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"--- Additional PC\n");CHKERRQ(ierr); 67522b0793eSJakub Kruzik ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 67622b0793eSJakub Kruzik ierr = PCView(def->pc,viewer);CHKERRQ(ierr); 67722b0793eSJakub Kruzik ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 67822b0793eSJakub Kruzik 6798513960bSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"--- Coarse solver\n");CHKERRQ(ierr); 6808513960bSJakub Kruzik ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 6818513960bSJakub Kruzik ierr = KSPView(def->WtAWinv,viewer);CHKERRQ(ierr); 6828513960bSJakub Kruzik ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 6838513960bSJakub Kruzik } 6848513960bSJakub Kruzik PetscFunctionReturn(0); 6858513960bSJakub Kruzik } 6868513960bSJakub Kruzik 68737eeb815SJakub Kruzik static PetscErrorCode PCSetFromOptions_Deflation(PetscOptionItems *PetscOptionsObject,PC pc) 68837eeb815SJakub Kruzik { 689880d05ceSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 69037eeb815SJakub Kruzik PetscErrorCode ierr; 69137eeb815SJakub Kruzik 69237eeb815SJakub Kruzik PetscFunctionBegin; 69337eeb815SJakub Kruzik ierr = PetscOptionsHead(PetscOptionsObject,"Deflation options");CHKERRQ(ierr); 694880d05ceSJakub Kruzik ierr = PetscOptionsEnum("-pc_deflation_compute_space","Compute deflation space","PCDeflationSetSpace",PCDeflationSpaceTypes,(PetscEnum)def->spacetype,(PetscEnum*)&def->spacetype,NULL);CHKERRQ(ierr); 695880d05ceSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_compute_space_size","Set size of the deflation space to compute","PCDeflationSetSpace",def->spacesize,&def->spacesize,NULL);CHKERRQ(ierr); 696880d05ceSJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_space_extend","Extend deflation space instead of truncating (wavelets)","PCDeflation",def->extendsp,&def->extendsp,NULL);CHKERRQ(ierr); 697880d05ceSJakub Kruzik //TODO add set function and fix manpages 698880d05ceSJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_initdef","Use only initialization step - Initdef","PCDeflation",def->init,&def->init,NULL);CHKERRQ(ierr); 699fcb31d99SJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_correct","Add coarse problem correction Q to P","PCDeflation",def->correct,&def->correct,NULL);CHKERRQ(ierr); 700fcb31d99SJakub Kruzik ierr = PetscOptionsReal("-pc_deflation_correct_val","Set multiple of Q to use as coarse problem correction","PCDeflation",def->correctfact,&def->correctfact,NULL);CHKERRQ(ierr); 701880d05ceSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_redfact","Reduction factor for coarse problem solution","PCDeflation",def->reductionfact,&def->reductionfact,NULL);CHKERRQ(ierr); 702880d05ceSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_max_nested_lvl","Maximum of nested deflation levels","PCDeflation",def->maxnestedlvl,&def->maxnestedlvl,NULL);CHKERRQ(ierr); 70337eeb815SJakub Kruzik ierr = PetscOptionsTail();CHKERRQ(ierr); 70437eeb815SJakub Kruzik PetscFunctionReturn(0); 70537eeb815SJakub Kruzik } 70637eeb815SJakub Kruzik 70737eeb815SJakub Kruzik /*MC 708e361f8b5SJakub Kruzik PCDEFLATION - Deflation preconditioner shifts part of the spectrum to zero (deflates) 709e361f8b5SJakub Kruzik or to a predefined value 71037eeb815SJakub Kruzik 71137eeb815SJakub Kruzik Options Database Key: 712e361f8b5SJakub Kruzik + -pc_deflation_type <init,pre,post> - selects approach to deflation (default: pre) 71337eeb815SJakub Kruzik - -pc_jacobi_abs - use the absolute value of the diagonal entry 71437eeb815SJakub Kruzik 71537eeb815SJakub Kruzik Level: beginner 71637eeb815SJakub Kruzik 71737eeb815SJakub Kruzik Notes: 718e361f8b5SJakub Kruzik todo 71937eeb815SJakub Kruzik 72037eeb815SJakub Kruzik .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 721e662bc50SJakub Kruzik PCDeflationSetType(), PCDeflationSetSpace() 72237eeb815SJakub Kruzik M*/ 72337eeb815SJakub Kruzik 72437eeb815SJakub Kruzik PETSC_EXTERN PetscErrorCode PCCreate_Deflation(PC pc) 72537eeb815SJakub Kruzik { 72637eeb815SJakub Kruzik PC_Deflation *def; 72737eeb815SJakub Kruzik PetscErrorCode ierr; 72837eeb815SJakub Kruzik 72937eeb815SJakub Kruzik PetscFunctionBegin; 73037eeb815SJakub Kruzik ierr = PetscNewLog(pc,&def);CHKERRQ(ierr); 73137eeb815SJakub Kruzik pc->data = (void*)def; 73237eeb815SJakub Kruzik 733e662bc50SJakub Kruzik def->init = PETSC_FALSE; 734e662bc50SJakub Kruzik def->correct = PETSC_FALSE; 735fcb31d99SJakub Kruzik def->correctfact = 1.0; 736e662bc50SJakub Kruzik def->reductionfact = -1; 737e662bc50SJakub Kruzik def->spacetype = PC_DEFLATION_SPACE_HAAR; 738e662bc50SJakub Kruzik def->spacesize = 1; 739e662bc50SJakub Kruzik def->extendsp = PETSC_FALSE; 740e662bc50SJakub Kruzik def->nestedlvl = 0; 741e662bc50SJakub Kruzik def->maxnestedlvl = 0; 74237eeb815SJakub Kruzik 74337eeb815SJakub Kruzik /* 74437eeb815SJakub Kruzik Set the pointers for the functions that are provided above. 74537eeb815SJakub Kruzik Now when the user-level routines (such as PCApply(), PCDestroy(), etc.) 74637eeb815SJakub Kruzik are called, they will automatically call these functions. Note we 74737eeb815SJakub Kruzik choose not to provide a couple of these functions since they are 74837eeb815SJakub Kruzik not needed. 74937eeb815SJakub Kruzik */ 75037eeb815SJakub Kruzik pc->ops->apply = PCApply_Deflation; 75137eeb815SJakub Kruzik pc->ops->applytranspose = PCApply_Deflation; 752b27c8092SJakub Kruzik pc->ops->presolve = PCPreSolve_Deflation; 753b27c8092SJakub Kruzik pc->ops->postsolve = 0; 75437eeb815SJakub Kruzik pc->ops->setup = PCSetUp_Deflation; 75537eeb815SJakub Kruzik pc->ops->reset = PCReset_Deflation; 75637eeb815SJakub Kruzik pc->ops->destroy = PCDestroy_Deflation; 75737eeb815SJakub Kruzik pc->ops->setfromoptions = PCSetFromOptions_Deflation; 7588513960bSJakub Kruzik pc->ops->view = PCView_Deflation; 75937eeb815SJakub Kruzik pc->ops->applyrichardson = 0; 76037eeb815SJakub Kruzik pc->ops->applysymmetricleft = 0; 76137eeb815SJakub Kruzik pc->ops->applysymmetricright = 0; 76237eeb815SJakub Kruzik 763e662bc50SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpace_C",PCDeflationSetSpace_Deflation);CHKERRQ(ierr); 7645c0c31c5SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetLvl_C",PCDeflationSetLvl_Deflation);CHKERRQ(ierr); 765268c6673SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetPC_C",PCDeflationGetPC_Deflation);CHKERRQ(ierr); 76622b0793eSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetPC_C",PCDeflationSetPC_Deflation);CHKERRQ(ierr); 767*e924b002SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCoarseMat_C",PCDeflationSetCoarseMat_Deflation);CHKERRQ(ierr); 7684a99276eSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetCoarseKSP_C",PCDeflationGetCoarseKSP_Deflation);CHKERRQ(ierr); 769f3eaa4f0SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCoarseKSP_C",PCDeflationSetCoarseKSP_Deflation);CHKERRQ(ierr); 77037eeb815SJakub Kruzik PetscFunctionReturn(0); 77137eeb815SJakub Kruzik } 77237eeb815SJakub Kruzik 773