1b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 23542a6bcSPeter Brune 33542a6bcSPeter Brune typedef struct { 4*b6266c6eSPeter Brune PetscInt sweeps; /* number of sweeps through the local subdomain before neighbor communication */ 5*b6266c6eSPeter Brune PetscInt max_its; /* maximum iterations of the inner pointblock solver */ 6*b6266c6eSPeter Brune PetscReal rtol; /* relative tolerance of the inner pointblock solver */ 7*b6266c6eSPeter Brune PetscReal abstol; /* absolute tolerance of the inner pointblock solver */ 8*b6266c6eSPeter Brune PetscReal stol; /* step tolerance of the inner pointblock solver */ 93542a6bcSPeter Brune } SNES_GS; 103542a6bcSPeter Brune 116cd56b8bSPeter Brune 12*b6266c6eSPeter Brune #undef __FUNCT__ 13*b6266c6eSPeter Brune #define __FUNCT__ "SNESGSSetTolerances" 14*b6266c6eSPeter Brune /*@ 15*b6266c6eSPeter Brune SNESGSSetTolerances - Sets various parameters used in convergence tests. 16*b6266c6eSPeter Brune 17*b6266c6eSPeter Brune Logically Collective on SNES 18*b6266c6eSPeter Brune 19*b6266c6eSPeter Brune Input Parameters: 20*b6266c6eSPeter Brune + snes - the SNES context 21*b6266c6eSPeter Brune . abstol - absolute convergence tolerance 22*b6266c6eSPeter Brune . rtol - relative convergence tolerance 23*b6266c6eSPeter Brune . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 24*b6266c6eSPeter Brune - maxit - maximum number of iterations 25*b6266c6eSPeter Brune 26*b6266c6eSPeter Brune 27*b6266c6eSPeter Brune Options Database Keys: 28*b6266c6eSPeter Brune + -snes_gs_atol <abstol> - Sets abstol 29*b6266c6eSPeter Brune . -snes_gs_rtol <rtol> - Sets rtol 30*b6266c6eSPeter Brune . -snes_gs_stol <stol> - Sets stol 31*b6266c6eSPeter Brune - -snes_max_it <maxit> - Sets maxit 32*b6266c6eSPeter Brune 33*b6266c6eSPeter Brune Level: intermediate 34*b6266c6eSPeter Brune 35*b6266c6eSPeter Brune .keywords: SNES, nonlinear, gauss-seidel, set, convergence, tolerances 36*b6266c6eSPeter Brune 37*b6266c6eSPeter Brune .seealso: SNESSetTrustRegionTolerance() 38*b6266c6eSPeter Brune @*/ 39*b6266c6eSPeter Brune PetscErrorCode SNESGSSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit) 40*b6266c6eSPeter Brune { 41*b6266c6eSPeter Brune SNES_GS *gs = (SNES_GS*)snes->data; 42*b6266c6eSPeter Brune 43*b6266c6eSPeter Brune PetscFunctionBegin; 44*b6266c6eSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45*b6266c6eSPeter Brune 46*b6266c6eSPeter Brune if (abstol != PETSC_DEFAULT) { 47*b6266c6eSPeter Brune if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 48*b6266c6eSPeter Brune gs->abstol = abstol; 49*b6266c6eSPeter Brune } 50*b6266c6eSPeter Brune if (rtol != PETSC_DEFAULT) { 51*b6266c6eSPeter Brune if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %G must be non-negative and less than 1.0",rtol); 52*b6266c6eSPeter Brune gs->rtol = rtol; 53*b6266c6eSPeter Brune } 54*b6266c6eSPeter Brune if (stol != PETSC_DEFAULT) { 55*b6266c6eSPeter Brune if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 56*b6266c6eSPeter Brune gs->stol = stol; 57*b6266c6eSPeter Brune } 58*b6266c6eSPeter Brune if (maxit != PETSC_DEFAULT) { 59*b6266c6eSPeter Brune if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 60*b6266c6eSPeter Brune gs->max_its = maxit; 61*b6266c6eSPeter Brune } 62*b6266c6eSPeter Brune PetscFunctionReturn(0); 63*b6266c6eSPeter Brune } 64*b6266c6eSPeter Brune 65*b6266c6eSPeter Brune #undef __FUNCT__ 66*b6266c6eSPeter Brune #define __FUNCT__ "SNESGSGetTolerances" 67*b6266c6eSPeter Brune /*@ 68*b6266c6eSPeter Brune SNESGSGetTolerances - Gets various parameters used in convergence tests. 69*b6266c6eSPeter Brune 70*b6266c6eSPeter Brune Not Collective 71*b6266c6eSPeter Brune 72*b6266c6eSPeter Brune Input Parameters: 73*b6266c6eSPeter Brune + snes - the SNES context 74*b6266c6eSPeter Brune . atol - absolute convergence tolerance 75*b6266c6eSPeter Brune . rtol - relative convergence tolerance 76*b6266c6eSPeter Brune . stol - convergence tolerance in terms of the norm 77*b6266c6eSPeter Brune of the change in the solution between steps 78*b6266c6eSPeter Brune - maxit - maximum number of iterations 79*b6266c6eSPeter Brune 80*b6266c6eSPeter Brune Notes: 81*b6266c6eSPeter Brune The user can specify PETSC_NULL for any parameter that is not needed. 82*b6266c6eSPeter Brune 83*b6266c6eSPeter Brune Level: intermediate 84*b6266c6eSPeter Brune 85*b6266c6eSPeter Brune .keywords: SNES, nonlinear, get, convergence, tolerances 86*b6266c6eSPeter Brune 87*b6266c6eSPeter Brune .seealso: SNESSetTolerances() 88*b6266c6eSPeter Brune @*/ 89*b6266c6eSPeter Brune PetscErrorCode SNESGSGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit) 90*b6266c6eSPeter Brune { 91*b6266c6eSPeter Brune SNES_GS *gs = (SNES_GS*)snes->data; 92*b6266c6eSPeter Brune 93*b6266c6eSPeter Brune PetscFunctionBegin; 94*b6266c6eSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 95*b6266c6eSPeter Brune if (atol) *atol = gs->abstol; 96*b6266c6eSPeter Brune if (rtol) *rtol = gs->rtol; 97*b6266c6eSPeter Brune if (stol) *stol = gs->stol; 98*b6266c6eSPeter Brune if (maxit) *maxit = gs->max_its; 99*b6266c6eSPeter Brune PetscFunctionReturn(0); 100*b6266c6eSPeter Brune } 1016cd56b8bSPeter Brune 1026cd56b8bSPeter Brune #undef __FUNCT__ 1036cd56b8bSPeter Brune #define __FUNCT__ "SNESGSSetSweeps" 1046cd56b8bSPeter Brune /*@ 1056cd56b8bSPeter Brune SNESGSSetSweeps - Sets the number of sweeps of GS to use. 1066cd56b8bSPeter Brune 1076cd56b8bSPeter Brune Input Parameters: 1086cd56b8bSPeter Brune + snes - the SNES context 1096cd56b8bSPeter Brune - sweeps - the number of sweeps of GS to perform. 1106cd56b8bSPeter Brune 1116cd56b8bSPeter Brune Level: intermediate 1126cd56b8bSPeter Brune 1136cd56b8bSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 1146cd56b8bSPeter Brune 1156cd56b8bSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGSGetSweeps() 1166cd56b8bSPeter Brune @*/ 1176cd56b8bSPeter Brune 1186cd56b8bSPeter Brune PetscErrorCode SNESGSSetSweeps(SNES snes, PetscInt sweeps) 1196cd56b8bSPeter Brune { 1206cd56b8bSPeter Brune SNES_GS *gs = (SNES_GS*)snes->data; 1216cd56b8bSPeter Brune 1226cd56b8bSPeter Brune PetscFunctionBegin; 1236cd56b8bSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1246cd56b8bSPeter Brune gs->sweeps = sweeps; 1256cd56b8bSPeter Brune PetscFunctionReturn(0); 1266cd56b8bSPeter Brune } 1276cd56b8bSPeter Brune 1286cd56b8bSPeter Brune #undef __FUNCT__ 1296cd56b8bSPeter Brune #define __FUNCT__ "SNESGSGetSweeps" 1306cd56b8bSPeter Brune /*@ 1316cd56b8bSPeter Brune SNESGSGetSweeps - Gets the number of sweeps GS will use. 1326cd56b8bSPeter Brune 1336cd56b8bSPeter Brune Input Parameters: 1346cd56b8bSPeter Brune . snes - the SNES context 1356cd56b8bSPeter Brune 1366cd56b8bSPeter Brune Output Parameters: 1376cd56b8bSPeter Brune . sweeps - the number of sweeps of GS to perform. 1386cd56b8bSPeter Brune 1396cd56b8bSPeter Brune Level: intermediate 1406cd56b8bSPeter Brune 1416cd56b8bSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 1426cd56b8bSPeter Brune 1436cd56b8bSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGSSetSweeps() 1446cd56b8bSPeter Brune @*/ 1456cd56b8bSPeter Brune PetscErrorCode SNESGSGetSweeps(SNES snes, PetscInt * sweeps) 1466cd56b8bSPeter Brune { 1476cd56b8bSPeter Brune SNES_GS *gs = (SNES_GS*)snes->data; 1486cd56b8bSPeter Brune 1496cd56b8bSPeter Brune PetscFunctionBegin; 1506cd56b8bSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1516cd56b8bSPeter Brune *sweeps = gs->sweeps; 1526cd56b8bSPeter Brune PetscFunctionReturn(0); 1536cd56b8bSPeter Brune } 1546cd56b8bSPeter Brune 1556cd56b8bSPeter Brune 1563542a6bcSPeter Brune #undef __FUNCT__ 157c79d6ae8SPeter Brune #define __FUNCT__ "SNESDefaultApplyGS" 1580adebc6cSBarry Smith PetscErrorCode SNESDefaultApplyGS(SNES snes,Vec X,Vec F,void *ctx) 1590adebc6cSBarry Smith { 160c79d6ae8SPeter Brune PetscFunctionBegin; 161c79d6ae8SPeter Brune /* see if there's a coloring on the DM */ 1621bdf7e34SPeter Brune 163c79d6ae8SPeter Brune PetscFunctionReturn(0); 164c79d6ae8SPeter Brune } 165c79d6ae8SPeter Brune 166c79d6ae8SPeter Brune #undef __FUNCT__ 1673542a6bcSPeter Brune #define __FUNCT__ "SNESReset_GS" 1683542a6bcSPeter Brune PetscErrorCode SNESReset_GS(SNES snes) 1693542a6bcSPeter Brune { 1703542a6bcSPeter Brune PetscFunctionBegin; 1713542a6bcSPeter Brune PetscFunctionReturn(0); 1723542a6bcSPeter Brune } 1733542a6bcSPeter Brune 1743542a6bcSPeter Brune #undef __FUNCT__ 1753542a6bcSPeter Brune #define __FUNCT__ "SNESDestroy_GS" 1763542a6bcSPeter Brune PetscErrorCode SNESDestroy_GS(SNES snes) 1773542a6bcSPeter Brune { 1783542a6bcSPeter Brune PetscErrorCode ierr; 1793542a6bcSPeter Brune 1803542a6bcSPeter Brune PetscFunctionBegin; 1813542a6bcSPeter Brune ierr = SNESReset_GS(snes);CHKERRQ(ierr); 18222d28d08SBarry Smith ierr = PetscFree(snes->data);CHKERRQ(ierr); 1833542a6bcSPeter Brune PetscFunctionReturn(0); 1843542a6bcSPeter Brune } 1853542a6bcSPeter Brune 1863542a6bcSPeter Brune #undef __FUNCT__ 1873542a6bcSPeter Brune #define __FUNCT__ "SNESSetUp_GS" 1883542a6bcSPeter Brune PetscErrorCode SNESSetUp_GS(SNES snes) 1893542a6bcSPeter Brune { 1903542a6bcSPeter Brune PetscFunctionBegin; 1913542a6bcSPeter Brune PetscFunctionReturn(0); 1923542a6bcSPeter Brune } 1933542a6bcSPeter Brune 1943542a6bcSPeter Brune #undef __FUNCT__ 1953542a6bcSPeter Brune #define __FUNCT__ "SNESSetFromOptions_GS" 1963542a6bcSPeter Brune PetscErrorCode SNESSetFromOptions_GS(SNES snes) 1973542a6bcSPeter Brune { 1986cd56b8bSPeter Brune SNES_GS *gs = (SNES_GS*)snes->data; 1993542a6bcSPeter Brune PetscErrorCode ierr; 200*b6266c6eSPeter Brune PetscInt sweeps,max_its=PETSC_DEFAULT; 201*b6266c6eSPeter Brune PetscReal rtol=PETSC_DEFAULT,atol=PETSC_DEFAULT,stol=PETSC_DEFAULT; 202*b6266c6eSPeter Brune PetscBool flg,flg1,flg2,flg3; 2033542a6bcSPeter Brune 2043542a6bcSPeter Brune PetscFunctionBegin; 2053542a6bcSPeter Brune ierr = PetscOptionsHead("SNES GS options");CHKERRQ(ierr); 2066cd56b8bSPeter Brune /* GS Options */ 207*b6266c6eSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",gs->sweeps,&sweeps,&flg);CHKERRQ(ierr); 208*b6266c6eSPeter Brune if (flg) { 209*b6266c6eSPeter Brune ierr = SNESGSSetSweeps(snes,sweeps);CHKERRQ(ierr); 210*b6266c6eSPeter Brune } 211*b6266c6eSPeter Brune ierr = PetscOptionsReal("-snes_gs_atol","Number of sweeps of GS to apply","SNESComputeGS",gs->abstol,&atol,&flg);CHKERRQ(ierr); 212*b6266c6eSPeter Brune ierr = PetscOptionsReal("-snes_gs_rtol","Number of sweeps of GS to apply","SNESComputeGS",gs->rtol,&rtol,&flg1);CHKERRQ(ierr); 213*b6266c6eSPeter Brune ierr = PetscOptionsReal("-snes_gs_stol","Number of sweeps of GS to apply","SNESComputeGS",gs->stol,&stol,&flg2);CHKERRQ(ierr); 214*b6266c6eSPeter Brune ierr = PetscOptionsInt("-snes_gs_max_it","Number of sweeps of GS to apply","SNESComputeGS",gs->max_its,&max_its,&flg3);CHKERRQ(ierr); 215*b6266c6eSPeter Brune if (flg || flg1 || flg2 || flg3) { 216*b6266c6eSPeter Brune ierr = SNESGSSetTolerances(snes,atol,rtol,stol,max_its);CHKERRQ(ierr); 217*b6266c6eSPeter Brune } 2184b32a720SPeter Brune ierr = PetscOptionsTail();CHKERRQ(ierr); 2193542a6bcSPeter Brune PetscFunctionReturn(0); 2203542a6bcSPeter Brune } 2213542a6bcSPeter Brune 2223542a6bcSPeter Brune #undef __FUNCT__ 2233542a6bcSPeter Brune #define __FUNCT__ "SNESView_GS" 2243542a6bcSPeter Brune PetscErrorCode SNESView_GS(SNES snes, PetscViewer viewer) 2253542a6bcSPeter Brune { 2263542a6bcSPeter Brune PetscFunctionBegin; 2273542a6bcSPeter Brune PetscFunctionReturn(0); 2283542a6bcSPeter Brune } 2293542a6bcSPeter Brune 2303542a6bcSPeter Brune #undef __FUNCT__ 2313542a6bcSPeter Brune #define __FUNCT__ "SNESSolve_GS" 2323542a6bcSPeter Brune PetscErrorCode SNESSolve_GS(SNES snes) 2333542a6bcSPeter Brune { 2343542a6bcSPeter Brune Vec F; 2353542a6bcSPeter Brune Vec X; 2363542a6bcSPeter Brune Vec B; 2373542a6bcSPeter Brune PetscInt i; 23806e07b1aSPeter Brune PetscReal fnorm; 2393542a6bcSPeter Brune PetscErrorCode ierr; 240534ebe21SPeter Brune SNESNormType normtype; 2413542a6bcSPeter Brune 2423542a6bcSPeter Brune PetscFunctionBegin; 2433542a6bcSPeter Brune 2443542a6bcSPeter Brune X = snes->vec_sol; 2453542a6bcSPeter Brune F = snes->vec_func; 2463542a6bcSPeter Brune B = snes->vec_rhs; 2473542a6bcSPeter Brune 248534ebe21SPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 249534ebe21SPeter Brune snes->iter = 0; 250534ebe21SPeter Brune snes->norm = 0.; 251534ebe21SPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 252526b802eSJed Brown snes->reason = SNES_CONVERGED_ITERATING; 253534ebe21SPeter Brune 254534ebe21SPeter Brune ierr = SNESGetNormType(snes, &normtype);CHKERRQ(ierr); 255fdacfa88SPeter Brune if (normtype == SNES_NORM_FUNCTION || normtype == SNES_NORM_INITIAL_ONLY || normtype == SNES_NORM_INITIAL_FINAL_ONLY) { 2563542a6bcSPeter Brune /* compute the initial function and preconditioned update delX */ 257e4ed7901SPeter Brune if (!snes->vec_func_init_set) { 2583542a6bcSPeter Brune ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 2593542a6bcSPeter Brune if (snes->domainerror) { 2603542a6bcSPeter Brune snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 2613542a6bcSPeter Brune PetscFunctionReturn(0); 2623542a6bcSPeter Brune } 263e4ed7901SPeter Brune } else { 264e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 265e4ed7901SPeter Brune } 266e4ed7901SPeter Brune 2673542a6bcSPeter Brune /* convergence test */ 268e4ed7901SPeter Brune if (!snes->norm_init_set) { 2693542a6bcSPeter Brune ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); /* fnorm <- ||F|| */ 2703542a6bcSPeter Brune if (PetscIsInfOrNanReal(fnorm)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 271e4ed7901SPeter Brune } else { 272e4ed7901SPeter Brune fnorm = snes->norm_init; 273e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 274e4ed7901SPeter Brune } 2753542a6bcSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 276e4ed7901SPeter Brune snes->iter = 0; 2773542a6bcSPeter Brune snes->norm = fnorm; 2783542a6bcSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 279e4ed7901SPeter Brune SNESLogConvHistory(snes,snes->norm,0); 280e4ed7901SPeter Brune ierr = SNESMonitor(snes,0,snes->norm);CHKERRQ(ierr); 2813542a6bcSPeter Brune 2823542a6bcSPeter Brune /* set parameter for default relative tolerance convergence test */ 2833542a6bcSPeter Brune snes->ttol = fnorm*snes->rtol; 284534ebe21SPeter Brune 2853542a6bcSPeter Brune /* test convergence */ 2863542a6bcSPeter Brune ierr = (*snes->ops->converged)(snes,0,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); 2873542a6bcSPeter Brune if (snes->reason) PetscFunctionReturn(0); 288534ebe21SPeter Brune } else { 289534ebe21SPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 290534ebe21SPeter Brune SNESLogConvHistory(snes,snes->norm,0); 291534ebe21SPeter Brune ierr = SNESMonitor(snes,0,snes->norm);CHKERRQ(ierr); 292534ebe21SPeter Brune } 293534ebe21SPeter Brune 2943542a6bcSPeter Brune 2953542a6bcSPeter Brune /* Call general purpose update function */ 2963542a6bcSPeter Brune if (snes->ops->update) { 2973542a6bcSPeter Brune ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr); 2983542a6bcSPeter Brune } 299534ebe21SPeter Brune 3003542a6bcSPeter Brune for (i = 0; i < snes->max_its; i++) { 3013542a6bcSPeter Brune ierr = SNESComputeGS(snes, B, X);CHKERRQ(ierr); 3024b32a720SPeter Brune /* only compute norms if requested or about to exit due to maximum iterations */ 303fdacfa88SPeter Brune if (normtype == SNES_NORM_FUNCTION || ((i == snes->max_its - 1) && (normtype == SNES_NORM_INITIAL_FINAL_ONLY || normtype == SNES_NORM_FINAL_ONLY))) { 3043542a6bcSPeter Brune ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 3053542a6bcSPeter Brune if (snes->domainerror) { 3063542a6bcSPeter Brune snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 3073542a6bcSPeter Brune PetscFunctionReturn(0); 3083542a6bcSPeter Brune } 3093542a6bcSPeter Brune ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); /* fnorm <- ||F|| */ 3103542a6bcSPeter Brune if (PetscIsInfOrNanReal(fnorm)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 311534ebe21SPeter Brune } 3123542a6bcSPeter Brune /* Monitor convergence */ 3133542a6bcSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 3143542a6bcSPeter Brune snes->iter = i+1; 3153542a6bcSPeter Brune snes->norm = fnorm; 3163542a6bcSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 3173542a6bcSPeter Brune SNESLogConvHistory(snes,snes->norm,0); 3183542a6bcSPeter Brune ierr = SNESMonitor(snes,snes->iter,snes->norm);CHKERRQ(ierr); 3193542a6bcSPeter Brune /* Test for convergence */ 320fdacfa88SPeter Brune if (normtype == SNES_NORM_FUNCTION) ierr = (*snes->ops->converged)(snes,snes->iter,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); 3213542a6bcSPeter Brune if (snes->reason) PetscFunctionReturn(0); 3223542a6bcSPeter Brune /* Call general purpose update function */ 3233542a6bcSPeter Brune if (snes->ops->update) { 3243542a6bcSPeter Brune ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr); 3253542a6bcSPeter Brune } 3263542a6bcSPeter Brune } 327fdacfa88SPeter Brune if (normtype == SNES_NORM_FUNCTION) { 328534ebe21SPeter Brune if (i == snes->max_its) { 329534ebe21SPeter Brune ierr = PetscInfo1(snes,"Maximum number of iterations has been reached: %D\n",snes->max_its);CHKERRQ(ierr); 330534ebe21SPeter Brune if (!snes->reason) snes->reason = SNES_DIVERGED_MAX_IT; 331534ebe21SPeter Brune } 332534ebe21SPeter Brune } else { 333526b802eSJed Brown if (!snes->reason) snes->reason = SNES_CONVERGED_ITS; /* GS is meant to be used as a preconditioner */ 334534ebe21SPeter Brune } 3353542a6bcSPeter Brune PetscFunctionReturn(0); 3363542a6bcSPeter Brune } 3373542a6bcSPeter Brune 3383542a6bcSPeter Brune /*MC 3393542a6bcSPeter Brune SNESGS - Just calls the user-provided solution routine provided with SNESSetGS() 3403542a6bcSPeter Brune 3413542a6bcSPeter Brune Level: advanced 3423542a6bcSPeter Brune 3433542a6bcSPeter Brune Notes: 3443542a6bcSPeter Brune the Gauss-Seidel smoother is inherited through composition. If a solver has been created with SNESGetPC(), it will have 3453542a6bcSPeter Brune its parent's Gauss-Seidel routine associated with it. 3463542a6bcSPeter Brune 3473542a6bcSPeter Brune .seealso: SNESCreate(), SNES, SNESSetType(), SNESSetGS(), SNESType (for list of available types) 3483542a6bcSPeter Brune M*/ 3493542a6bcSPeter Brune 3503542a6bcSPeter Brune EXTERN_C_BEGIN 3513542a6bcSPeter Brune #undef __FUNCT__ 3523542a6bcSPeter Brune #define __FUNCT__ "SNESCreate_GS" 3533542a6bcSPeter Brune PetscErrorCode SNESCreate_GS(SNES snes) 3543542a6bcSPeter Brune { 3553542a6bcSPeter Brune SNES_GS *gs; 3563542a6bcSPeter Brune PetscErrorCode ierr; 3573542a6bcSPeter Brune 3583542a6bcSPeter Brune PetscFunctionBegin; 3593542a6bcSPeter Brune snes->ops->destroy = SNESDestroy_GS; 3603542a6bcSPeter Brune snes->ops->setup = SNESSetUp_GS; 3613542a6bcSPeter Brune snes->ops->setfromoptions = SNESSetFromOptions_GS; 3623542a6bcSPeter Brune snes->ops->view = SNESView_GS; 3633542a6bcSPeter Brune snes->ops->solve = SNESSolve_GS; 3643542a6bcSPeter Brune snes->ops->reset = SNESReset_GS; 3653542a6bcSPeter Brune 3663542a6bcSPeter Brune snes->usesksp = PETSC_FALSE; 3673542a6bcSPeter Brune snes->usespc = PETSC_FALSE; 3683542a6bcSPeter Brune 36988976e71SPeter Brune if (!snes->tolerancesset) { 3700e444f03SPeter Brune snes->max_its = 10000; 3710e444f03SPeter Brune snes->max_funcs = 10000; 37288976e71SPeter Brune } 3730e444f03SPeter Brune 3743542a6bcSPeter Brune ierr = PetscNewLog(snes, SNES_GS, &gs);CHKERRQ(ierr); 3756cd56b8bSPeter Brune 3766cd56b8bSPeter Brune gs->sweeps = 1; 377*b6266c6eSPeter Brune gs->rtol = 1e-5; 378*b6266c6eSPeter Brune gs->abstol = 1e-15; 379*b6266c6eSPeter Brune gs->stol = 1e-12; 380*b6266c6eSPeter Brune gs->max_its = 50; 3816cd56b8bSPeter Brune 3823542a6bcSPeter Brune snes->data = (void*) gs; 3836cd56b8bSPeter Brune 3843542a6bcSPeter Brune PetscFunctionReturn(0); 3853542a6bcSPeter Brune } 3863542a6bcSPeter Brune EXTERN_C_END 387