1*3542a6bcSPeter Brune #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 2*3542a6bcSPeter Brune 3*3542a6bcSPeter Brune typedef struct { 4*3542a6bcSPeter Brune PetscInt sweeps; 5*3542a6bcSPeter Brune } SNES_GS; 6*3542a6bcSPeter Brune 7*3542a6bcSPeter Brune #undef __FUNCT__ 8*3542a6bcSPeter Brune #define __FUNCT__ "SNESReset_GS" 9*3542a6bcSPeter Brune PetscErrorCode SNESReset_GS(SNES snes) 10*3542a6bcSPeter Brune { 11*3542a6bcSPeter Brune PetscFunctionBegin; 12*3542a6bcSPeter Brune PetscFunctionReturn(0); 13*3542a6bcSPeter Brune } 14*3542a6bcSPeter Brune 15*3542a6bcSPeter Brune #undef __FUNCT__ 16*3542a6bcSPeter Brune #define __FUNCT__ "SNESDestroy_GS" 17*3542a6bcSPeter Brune PetscErrorCode SNESDestroy_GS(SNES snes) 18*3542a6bcSPeter Brune { 19*3542a6bcSPeter Brune PetscErrorCode ierr; 20*3542a6bcSPeter Brune 21*3542a6bcSPeter Brune PetscFunctionBegin; 22*3542a6bcSPeter Brune ierr = SNESReset_GS(snes);CHKERRQ(ierr); 23*3542a6bcSPeter Brune ierr = PetscFree(snes->data); 24*3542a6bcSPeter Brune PetscFunctionReturn(0); 25*3542a6bcSPeter Brune } 26*3542a6bcSPeter Brune 27*3542a6bcSPeter Brune #undef __FUNCT__ 28*3542a6bcSPeter Brune #define __FUNCT__ "SNESSetUp_GS" 29*3542a6bcSPeter Brune PetscErrorCode SNESSetUp_GS(SNES snes) 30*3542a6bcSPeter Brune { 31*3542a6bcSPeter Brune PetscFunctionBegin; 32*3542a6bcSPeter Brune PetscFunctionReturn(0); 33*3542a6bcSPeter Brune } 34*3542a6bcSPeter Brune 35*3542a6bcSPeter Brune #undef __FUNCT__ 36*3542a6bcSPeter Brune #define __FUNCT__ "SNESSetFromOptions_GS" 37*3542a6bcSPeter Brune PetscErrorCode SNESSetFromOptions_GS(SNES snes) 38*3542a6bcSPeter Brune { 39*3542a6bcSPeter Brune PetscErrorCode ierr; 40*3542a6bcSPeter Brune 41*3542a6bcSPeter Brune PetscFunctionBegin; 42*3542a6bcSPeter Brune ierr = PetscOptionsHead("SNES GS options");CHKERRQ(ierr); 43*3542a6bcSPeter Brune PetscFunctionReturn(0); 44*3542a6bcSPeter Brune } 45*3542a6bcSPeter Brune 46*3542a6bcSPeter Brune #undef __FUNCT__ 47*3542a6bcSPeter Brune #define __FUNCT__ "SNESView_GS" 48*3542a6bcSPeter Brune PetscErrorCode SNESView_GS(SNES snes, PetscViewer viewer) 49*3542a6bcSPeter Brune { 50*3542a6bcSPeter Brune PetscFunctionBegin; 51*3542a6bcSPeter Brune PetscFunctionReturn(0); 52*3542a6bcSPeter Brune } 53*3542a6bcSPeter Brune 54*3542a6bcSPeter Brune #undef __FUNCT__ 55*3542a6bcSPeter Brune #define __FUNCT__ "SNESSolve_GS" 56*3542a6bcSPeter Brune PetscErrorCode SNESSolve_GS(SNES snes) 57*3542a6bcSPeter Brune { 58*3542a6bcSPeter Brune Vec F; 59*3542a6bcSPeter Brune Vec X; 60*3542a6bcSPeter Brune Vec B; 61*3542a6bcSPeter Brune PetscInt i; 62*3542a6bcSPeter Brune PetscScalar fnorm; 63*3542a6bcSPeter Brune PetscErrorCode ierr; 64*3542a6bcSPeter Brune 65*3542a6bcSPeter Brune PetscFunctionBegin; 66*3542a6bcSPeter Brune 67*3542a6bcSPeter Brune X = snes->vec_sol; 68*3542a6bcSPeter Brune F = snes->vec_func; 69*3542a6bcSPeter Brune B = snes->vec_rhs; 70*3542a6bcSPeter Brune 71*3542a6bcSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 72*3542a6bcSPeter Brune snes->iter = 0; 73*3542a6bcSPeter Brune snes->norm = 0.; 74*3542a6bcSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 75*3542a6bcSPeter Brune 76*3542a6bcSPeter Brune snes->reason = SNES_CONVERGED_ITS; 77*3542a6bcSPeter Brune /* compute the initial function and preconditioned update delX */ 78*3542a6bcSPeter Brune ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 79*3542a6bcSPeter Brune if (snes->domainerror) { 80*3542a6bcSPeter Brune snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 81*3542a6bcSPeter Brune PetscFunctionReturn(0); 82*3542a6bcSPeter Brune } 83*3542a6bcSPeter Brune /* convergence test */ 84*3542a6bcSPeter Brune ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); /* fnorm <- ||F|| */ 85*3542a6bcSPeter Brune if (PetscIsInfOrNanReal(fnorm)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 86*3542a6bcSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 87*3542a6bcSPeter Brune snes->norm = fnorm; 88*3542a6bcSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 89*3542a6bcSPeter Brune SNESLogConvHistory(snes,fnorm,0); 90*3542a6bcSPeter Brune ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr); 91*3542a6bcSPeter Brune 92*3542a6bcSPeter Brune /* set parameter for default relative tolerance convergence test */ 93*3542a6bcSPeter Brune snes->ttol = fnorm*snes->rtol; 94*3542a6bcSPeter Brune /* test convergence */ 95*3542a6bcSPeter Brune ierr = (*snes->ops->converged)(snes,0,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); 96*3542a6bcSPeter Brune if (snes->reason) PetscFunctionReturn(0); 97*3542a6bcSPeter Brune 98*3542a6bcSPeter Brune /* Call general purpose update function */ 99*3542a6bcSPeter Brune if (snes->ops->update) { 100*3542a6bcSPeter Brune ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr); 101*3542a6bcSPeter Brune } 102*3542a6bcSPeter Brune for(i = 0; i < snes->max_its; i++) { 103*3542a6bcSPeter Brune ierr = SNESComputeGS(snes, B, X);CHKERRQ(ierr); 104*3542a6bcSPeter Brune ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 105*3542a6bcSPeter Brune if (snes->domainerror) { 106*3542a6bcSPeter Brune snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 107*3542a6bcSPeter Brune PetscFunctionReturn(0); 108*3542a6bcSPeter Brune } 109*3542a6bcSPeter Brune ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); /* fnorm <- ||F|| */ 110*3542a6bcSPeter Brune if (PetscIsInfOrNanReal(fnorm)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 111*3542a6bcSPeter Brune /* Monitor convergence */ 112*3542a6bcSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 113*3542a6bcSPeter Brune snes->iter = i+1; 114*3542a6bcSPeter Brune snes->norm = fnorm; 115*3542a6bcSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 116*3542a6bcSPeter Brune SNESLogConvHistory(snes,snes->norm,0); 117*3542a6bcSPeter Brune ierr = SNESMonitor(snes,snes->iter,snes->norm);CHKERRQ(ierr); 118*3542a6bcSPeter Brune 119*3542a6bcSPeter Brune /* Test for convergence */ 120*3542a6bcSPeter Brune ierr = (*snes->ops->converged)(snes,snes->iter,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); 121*3542a6bcSPeter Brune if (snes->reason) PetscFunctionReturn(0); 122*3542a6bcSPeter Brune 123*3542a6bcSPeter Brune /* Call general purpose update function */ 124*3542a6bcSPeter Brune if (snes->ops->update) { 125*3542a6bcSPeter Brune ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr); 126*3542a6bcSPeter Brune } 127*3542a6bcSPeter Brune } 128*3542a6bcSPeter Brune ierr = PetscInfo1(snes, "Maximum number of iterations has been reached: %D\n", snes->max_its);CHKERRQ(ierr); 129*3542a6bcSPeter Brune if (!snes->reason) snes->reason = SNES_DIVERGED_MAX_IT; 130*3542a6bcSPeter Brune PetscFunctionReturn(0); 131*3542a6bcSPeter Brune } 132*3542a6bcSPeter Brune 133*3542a6bcSPeter Brune /*MC 134*3542a6bcSPeter Brune SNESGS - Just calls the user-provided solution routine provided with SNESSetGS() 135*3542a6bcSPeter Brune 136*3542a6bcSPeter Brune Level: advanced 137*3542a6bcSPeter Brune 138*3542a6bcSPeter Brune Notes: 139*3542a6bcSPeter Brune the Gauss-Seidel smoother is inherited through composition. If a solver has been created with SNESGetPC(), it will have 140*3542a6bcSPeter Brune its parent's Gauss-Seidel routine associated with it. 141*3542a6bcSPeter Brune 142*3542a6bcSPeter Brune .seealso: SNESCreate(), SNES, SNESSetType(), SNESSetGS(), SNESType (for list of available types) 143*3542a6bcSPeter Brune M*/ 144*3542a6bcSPeter Brune 145*3542a6bcSPeter Brune EXTERN_C_BEGIN 146*3542a6bcSPeter Brune #undef __FUNCT__ 147*3542a6bcSPeter Brune #define __FUNCT__ "SNESCreate_GS" 148*3542a6bcSPeter Brune PetscErrorCode SNESCreate_GS(SNES snes) 149*3542a6bcSPeter Brune { 150*3542a6bcSPeter Brune SNES_GS *gs; 151*3542a6bcSPeter Brune PetscErrorCode ierr; 152*3542a6bcSPeter Brune 153*3542a6bcSPeter Brune PetscFunctionBegin; 154*3542a6bcSPeter Brune snes->ops->destroy = SNESDestroy_GS; 155*3542a6bcSPeter Brune snes->ops->setup = SNESSetUp_GS; 156*3542a6bcSPeter Brune snes->ops->setfromoptions = SNESSetFromOptions_GS; 157*3542a6bcSPeter Brune snes->ops->view = SNESView_GS; 158*3542a6bcSPeter Brune snes->ops->solve = SNESSolve_GS; 159*3542a6bcSPeter Brune snes->ops->reset = SNESReset_GS; 160*3542a6bcSPeter Brune 161*3542a6bcSPeter Brune snes->usesksp = PETSC_FALSE; 162*3542a6bcSPeter Brune snes->usespc = PETSC_FALSE; 163*3542a6bcSPeter Brune 164*3542a6bcSPeter Brune ierr = PetscNewLog(snes, SNES_GS, &gs);CHKERRQ(ierr); 165*3542a6bcSPeter Brune snes->data = (void*) gs; 166*3542a6bcSPeter Brune PetscFunctionReturn(0); 167*3542a6bcSPeter Brune } 168*3542a6bcSPeter Brune EXTERN_C_END 169