113a62661SPeter Brune #include <../src/snes/impls/ngmres/snesngmres.h> /*I "petscsnes.h" I*/ 219653cdaSPeter Brune #include <petscblaslapack.h> 3fced5a79SAsbjørn Nilsen Riseth #include <petscdm.h> 4a312c225SMatthew G Knepley 56a6fc655SJed Brown const char *const SNESNGMRESRestartTypes[] = {"NONE","PERIODIC","DIFFERENCE","SNESNGMRESRestartType","SNES_NGMRES_RESTART_",0}; 66a6fc655SJed Brown const char *const SNESNGMRESSelectTypes[] = {"NONE","DIFFERENCE","LINESEARCH","SNESNGMRESSelectType","SNES_NGMRES_SELECT_",0}; 713a62661SPeter Brune 8a312c225SMatthew G Knepley #undef __FUNCT__ 9a312c225SMatthew G Knepley #define __FUNCT__ "SNESReset_NGMRES" 10a312c225SMatthew G Knepley PetscErrorCode SNESReset_NGMRES(SNES snes) 11a312c225SMatthew G Knepley { 12a312c225SMatthew G Knepley SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 13a312c225SMatthew G Knepley PetscErrorCode ierr; 14a312c225SMatthew G Knepley 15a312c225SMatthew G Knepley PetscFunctionBegin; 16f109b39eSPeter Brune ierr = VecDestroyVecs(ngmres->msize,&ngmres->Fdot);CHKERRQ(ierr); 17f109b39eSPeter Brune ierr = VecDestroyVecs(ngmres->msize,&ngmres->Xdot);CHKERRQ(ierr); 18f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&ngmres->additive_linesearch);CHKERRQ(ierr); 19a312c225SMatthew G Knepley PetscFunctionReturn(0); 20a312c225SMatthew G Knepley } 21a312c225SMatthew G Knepley 22a312c225SMatthew G Knepley #undef __FUNCT__ 23a312c225SMatthew G Knepley #define __FUNCT__ "SNESDestroy_NGMRES" 24a312c225SMatthew G Knepley PetscErrorCode SNESDestroy_NGMRES(SNES snes) 25a312c225SMatthew G Knepley { 26a312c225SMatthew G Knepley PetscErrorCode ierr; 2778440776SJed Brown SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 28a312c225SMatthew G Knepley 29a312c225SMatthew G Knepley PetscFunctionBegin; 30a312c225SMatthew G Knepley ierr = SNESReset_NGMRES(snes);CHKERRQ(ierr); 31f109b39eSPeter Brune ierr = PetscFree5(ngmres->h,ngmres->beta,ngmres->xi,ngmres->fnorms,ngmres->q);CHKERRQ(ierr); 3219653cdaSPeter Brune ierr = PetscFree(ngmres->s);CHKERRQ(ierr); 3318aa0c0cSPeter Brune ierr = PetscFree(ngmres->xnorms);CHKERRQ(ierr); 3419653cdaSPeter Brune #if PETSC_USE_COMPLEX 3522d28d08SBarry Smith ierr = PetscFree(ngmres->rwork);CHKERRQ(ierr); 3619653cdaSPeter Brune #endif 3722d28d08SBarry Smith ierr = PetscFree(ngmres->work);CHKERRQ(ierr); 3822d28d08SBarry Smith ierr = PetscFree(snes->data);CHKERRQ(ierr); 39a312c225SMatthew G Knepley PetscFunctionReturn(0); 40a312c225SMatthew G Knepley } 41a312c225SMatthew G Knepley 42a312c225SMatthew G Knepley #undef __FUNCT__ 43a312c225SMatthew G Knepley #define __FUNCT__ "SNESSetUp_NGMRES" 44a312c225SMatthew G Knepley PetscErrorCode SNESSetUp_NGMRES(SNES snes) 45a312c225SMatthew G Knepley { 46a312c225SMatthew G Knepley SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 47e7058c64SPeter Brune const char *optionsprefix; 4819653cdaSPeter Brune PetscInt msize,hsize; 49a312c225SMatthew G Knepley PetscErrorCode ierr; 50fced5a79SAsbjørn Nilsen Riseth DM dm; 51a312c225SMatthew G Knepley 52a312c225SMatthew G Knepley PetscFunctionBegin; 5346159c86SPeter Brune if (snes->pc && snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_UNPRECONDITIONED) { 5446159c86SPeter Brune SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"SNESNGMRES does not support left preconditioning with unpreconditioned function"); 5546159c86SPeter Brune } 566c67d002SPeter Brune if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_DEFAULT) snes->functype = SNES_FUNCTION_PRECONDITIONED; 57fa0ddf94SBarry Smith ierr = SNESSetWorkVecs(snes,5);CHKERRQ(ierr); 58fced5a79SAsbjørn Nilsen Riseth 59fced5a79SAsbjørn Nilsen Riseth if (!snes->vec_sol) { 60fced5a79SAsbjørn Nilsen Riseth ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 61fced5a79SAsbjørn Nilsen Riseth ierr = DMCreateGlobalVector(dm,&snes->vec_sol);CHKERRQ(ierr); 62fced5a79SAsbjørn Nilsen Riseth } 63fced5a79SAsbjørn Nilsen Riseth 6478440776SJed Brown if (!ngmres->Xdot) {ierr = VecDuplicateVecs(snes->vec_sol,ngmres->msize,&ngmres->Xdot);CHKERRQ(ierr);} 6578440776SJed Brown if (!ngmres->Fdot) {ierr = VecDuplicateVecs(snes->vec_sol,ngmres->msize,&ngmres->Fdot);CHKERRQ(ierr);} 6678440776SJed Brown if (!ngmres->setup_called) { 67087dfb9eSxuemin msize = ngmres->msize; /* restart size */ 6819653cdaSPeter Brune hsize = msize * msize; 69087dfb9eSxuemin 7098b3e84cSPeter Brune /* explicit least squares minimization solve */ 71dcca6d9dSJed Brown ierr = PetscMalloc5(hsize,&ngmres->h, msize,&ngmres->beta, msize,&ngmres->xi, msize,&ngmres->fnorms, hsize,&ngmres->q);CHKERRQ(ierr); 72785e854fSJed Brown ierr = PetscMalloc1(msize,&ngmres->xnorms);CHKERRQ(ierr); 7319653cdaSPeter Brune ngmres->nrhs = 1; 7419653cdaSPeter Brune ngmres->lda = msize; 7519653cdaSPeter Brune ngmres->ldb = msize; 76785e854fSJed Brown ierr = PetscMalloc1(msize,&ngmres->s);CHKERRQ(ierr); 7719653cdaSPeter Brune ierr = PetscMemzero(ngmres->h, hsize*sizeof(PetscScalar));CHKERRQ(ierr); 7819653cdaSPeter Brune ierr = PetscMemzero(ngmres->q, hsize*sizeof(PetscScalar));CHKERRQ(ierr); 7919653cdaSPeter Brune ierr = PetscMemzero(ngmres->xi, msize*sizeof(PetscScalar));CHKERRQ(ierr); 8019653cdaSPeter Brune ierr = PetscMemzero(ngmres->beta,msize*sizeof(PetscScalar));CHKERRQ(ierr); 8119653cdaSPeter Brune ngmres->lwork = 12*msize; 8219653cdaSPeter Brune #if PETSC_USE_COMPLEX 83854ce69bSBarry Smith ierr = PetscMalloc1(ngmres->lwork,&ngmres->rwork);CHKERRQ(ierr); 8419653cdaSPeter Brune #endif 85854ce69bSBarry Smith ierr = PetscMalloc1(ngmres->lwork,&ngmres->work);CHKERRQ(ierr); 8678440776SJed Brown } 87e7058c64SPeter Brune 88e7058c64SPeter Brune /* linesearch setup */ 89e7058c64SPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 90e7058c64SPeter Brune 9113a62661SPeter Brune if (ngmres->select_type == SNES_NGMRES_SELECT_LINESEARCH) { 92ce94432eSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes),&ngmres->additive_linesearch);CHKERRQ(ierr); 93f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(ngmres->additive_linesearch,snes);CHKERRQ(ierr); 941a4f838cSPeter Brune ierr = SNESLineSearchSetType(ngmres->additive_linesearch,SNESLINESEARCHL2);CHKERRQ(ierr); 95f1c6b773SPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(ngmres->additive_linesearch,"additive_");CHKERRQ(ierr); 96f1c6b773SPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(ngmres->additive_linesearch,optionsprefix);CHKERRQ(ierr); 97f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(ngmres->additive_linesearch);CHKERRQ(ierr); 98e7058c64SPeter Brune } 99e7058c64SPeter Brune 10078440776SJed Brown ngmres->setup_called = PETSC_TRUE; 101a312c225SMatthew G Knepley PetscFunctionReturn(0); 102a312c225SMatthew G Knepley } 103a312c225SMatthew G Knepley 104a312c225SMatthew G Knepley #undef __FUNCT__ 105a312c225SMatthew G Knepley #define __FUNCT__ "SNESSetFromOptions_NGMRES" 1068c34d3f5SBarry Smith PetscErrorCode SNESSetFromOptions_NGMRES(PetscOptions *PetscOptionsObject,SNES snes) 107a312c225SMatthew G Knepley { 108a312c225SMatthew G Knepley SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 109a312c225SMatthew G Knepley PetscErrorCode ierr; 11094ae4db5SBarry Smith PetscBool debug = PETSC_FALSE; 111f1c6b773SPeter Brune SNESLineSearch linesearch; 1120adebc6cSBarry Smith 113a312c225SMatthew G Knepley PetscFunctionBegin; 114e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"SNES NGMRES options");CHKERRQ(ierr); 11513a62661SPeter Brune ierr = PetscOptionsEnum("-snes_ngmres_select_type","Select type","SNESNGMRESSetSelectType",SNESNGMRESSelectTypes, 1160298fd71SBarry Smith (PetscEnum)ngmres->select_type,(PetscEnum*)&ngmres->select_type,NULL);CHKERRQ(ierr); 11713a62661SPeter Brune ierr = PetscOptionsEnum("-snes_ngmres_restart_type","Restart type","SNESNGMRESSetRestartType",SNESNGMRESRestartTypes, 1180298fd71SBarry Smith (PetscEnum)ngmres->restart_type,(PetscEnum*)&ngmres->restart_type,NULL);CHKERRQ(ierr); 1190298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ngmres_candidate", "Use candidate storage", "SNES",ngmres->candidate,&ngmres->candidate,NULL);CHKERRQ(ierr); 120077c4231SPeter Brune ierr = PetscOptionsBool("-snes_ngmres_approxfunc","Linearly approximate the function", "SNES",ngmres->approxfunc,&ngmres->approxfunc,NULL);CHKERRQ(ierr); 1210298fd71SBarry Smith ierr = PetscOptionsInt("-snes_ngmres_m", "Number of directions", "SNES",ngmres->msize,&ngmres->msize,NULL);CHKERRQ(ierr); 1220298fd71SBarry Smith ierr = PetscOptionsInt("-snes_ngmres_restart", "Iterations before forced restart", "SNES",ngmres->restart_periodic,&ngmres->restart_periodic,NULL);CHKERRQ(ierr); 1230298fd71SBarry Smith ierr = PetscOptionsInt("-snes_ngmres_restart_it", "Tolerance iterations before restart","SNES",ngmres->restart_it,&ngmres->restart_it,NULL);CHKERRQ(ierr); 1240298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ngmres_monitor", "Monitor actions of NGMRES", "SNES",ngmres->monitor ? PETSC_TRUE : PETSC_FALSE,&debug,NULL);CHKERRQ(ierr); 125dfbf837cSBarry Smith if (debug) { 126ce94432eSBarry Smith ngmres->monitor = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 127dfbf837cSBarry Smith } 1280298fd71SBarry Smith ierr = PetscOptionsReal("-snes_ngmres_gammaA", "Residual selection constant", "SNES",ngmres->gammaA,&ngmres->gammaA,NULL);CHKERRQ(ierr); 1290298fd71SBarry Smith ierr = PetscOptionsReal("-snes_ngmres_gammaC", "Residual restart constant", "SNES",ngmres->gammaC,&ngmres->gammaC,NULL);CHKERRQ(ierr); 1300298fd71SBarry Smith ierr = PetscOptionsReal("-snes_ngmres_epsilonB", "Difference selection constant", "SNES",ngmres->epsilonB,&ngmres->epsilonB,NULL);CHKERRQ(ierr); 1310298fd71SBarry Smith ierr = PetscOptionsReal("-snes_ngmres_deltaB", "Difference residual selection constant", "SNES",ngmres->deltaB,&ngmres->deltaB,NULL);CHKERRQ(ierr); 1320298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ngmres_single_reduction", "Aggregate reductions", "SNES",ngmres->singlereduction,&ngmres->singlereduction,NULL);CHKERRQ(ierr); 133*23b3e82cSAsbjørn Nilsen Riseth ierr = PetscOptionsBool("-snes_ngmres_restart_fm_rise", "Restart on F_M residual rise", "SNESNGMRESSetRestartFmRise",ngmres->restart_fm_rise,&ngmres->restart_fm_rise,NULL);CHKERRQ(ierr); 134a312c225SMatthew G Knepley ierr = PetscOptionsTail();CHKERRQ(ierr); 1356a7cf640SPeter Brune if ((ngmres->gammaA > ngmres->gammaC) && (ngmres->gammaC > 2.)) ngmres->gammaC = ngmres->gammaA; 1369e764e56SPeter Brune 1379e764e56SPeter Brune /* set the default type of the line search if the user hasn't already. */ 1389e764e56SPeter Brune if (!snes->linesearch) { 1397601faf0SJed Brown ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 1401a4f838cSPeter Brune ierr = SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);CHKERRQ(ierr); 1419e764e56SPeter Brune } 142a312c225SMatthew G Knepley PetscFunctionReturn(0); 143a312c225SMatthew G Knepley } 144a312c225SMatthew G Knepley 145a312c225SMatthew G Knepley #undef __FUNCT__ 146a312c225SMatthew G Knepley #define __FUNCT__ "SNESView_NGMRES" 147a312c225SMatthew G Knepley PetscErrorCode SNESView_NGMRES(SNES snes,PetscViewer viewer) 148a312c225SMatthew G Knepley { 149a312c225SMatthew G Knepley SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 150a312c225SMatthew G Knepley PetscBool iascii; 151a312c225SMatthew G Knepley PetscErrorCode ierr; 152a312c225SMatthew G Knepley 153a312c225SMatthew G Knepley PetscFunctionBegin; 154251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 155a312c225SMatthew G Knepley if (iascii) { 156f109b39eSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," Number of stored past updates: %d\n", ngmres->msize);CHKERRQ(ierr); 157f109b39eSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," Residual selection: gammaA=%1.0e, gammaC=%1.0e\n",ngmres->gammaA,ngmres->gammaC);CHKERRQ(ierr); 158f109b39eSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," Difference restart: epsilonB=%1.0e, deltaB=%1.0e\n",ngmres->epsilonB,ngmres->deltaB);CHKERRQ(ierr); 159*23b3e82cSAsbjørn Nilsen Riseth ierr = PetscViewerASCIIPrintf(viewer," Restart on F_M residual increase: %s\n",ngmres->restart_fm_rise?"TRUE":"FALSE");CHKERRQ(ierr); 160a312c225SMatthew G Knepley } 161a312c225SMatthew G Knepley PetscFunctionReturn(0); 162a312c225SMatthew G Knepley } 163a312c225SMatthew G Knepley 164a312c225SMatthew G Knepley #undef __FUNCT__ 165a312c225SMatthew G Knepley #define __FUNCT__ "SNESSolve_NGMRES" 166a312c225SMatthew G Knepley PetscErrorCode SNESSolve_NGMRES(SNES snes) 167a312c225SMatthew G Knepley { 168087dfb9eSxuemin SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 16998b3e84cSPeter Brune /* present solution, residual, and preconditioned residual */ 1709f425c49SPeter Brune Vec X,F,B,D,Y; 171f109b39eSPeter Brune 172f109b39eSPeter Brune /* candidate linear combination answers */ 173ddd40ce5SPeter Brune Vec XA,FA,XM,FM; 17419653cdaSPeter Brune 17598b3e84cSPeter Brune /* coefficients and RHS to the minimization problem */ 17618aa0c0cSPeter Brune PetscReal fnorm,fMnorm,fAnorm; 177b3c6a99cSPeter Brune PetscReal xnorm,xMnorm,xAnorm; 178b3c6a99cSPeter Brune PetscReal ynorm,yMnorm,yAnorm; 17938774f0aSPeter Brune PetscInt k,k_restart,l,ivec,restart_count = 0; 18019653cdaSPeter Brune 18198b3e84cSPeter Brune /* solution selection data */ 18238774f0aSPeter Brune PetscBool selectRestart; 18338774f0aSPeter Brune PetscReal dnorm,dminnorm = 0.0; 184b3c6a99cSPeter Brune PetscReal fminnorm; 18519653cdaSPeter Brune 1861e633543SBarry Smith SNESConvergedReason reason; 187422a814eSBarry Smith SNESLineSearchReason lssucceed; 188a312c225SMatthew G Knepley PetscErrorCode ierr; 189a312c225SMatthew G Knepley 190a312c225SMatthew G Knepley PetscFunctionBegin; 191c579b300SPatrick Farrell 192c579b300SPatrick Farrell if (snes->xl || snes->xu || snes->ops->computevariablebounds) { 193c579b300SPatrick Farrell SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE, "SNES solver %s does not support bounds", ((PetscObject)snes)->type_name); 194c579b300SPatrick Farrell } 195c579b300SPatrick Farrell 196fffbeea8SBarry Smith ierr = PetscCitationsRegister(SNESCitation,&SNEScite);CHKERRQ(ierr); 19798b3e84cSPeter Brune /* variable initialization */ 198a312c225SMatthew G Knepley snes->reason = SNES_CONVERGED_ITERATING; 199f109b39eSPeter Brune X = snes->vec_sol; 200f109b39eSPeter Brune F = snes->vec_func; 201f109b39eSPeter Brune B = snes->vec_rhs; 202f109b39eSPeter Brune XA = snes->vec_sol_update; 203f109b39eSPeter Brune FA = snes->work[0]; 204f109b39eSPeter Brune D = snes->work[1]; 205f109b39eSPeter Brune 206f109b39eSPeter Brune /* work for the line search */ 207f109b39eSPeter Brune Y = snes->work[2]; 2089f425c49SPeter Brune XM = snes->work[3]; 2099f425c49SPeter Brune FM = snes->work[4]; 210a312c225SMatthew G Knepley 211e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 212a312c225SMatthew G Knepley snes->iter = 0; 213a312c225SMatthew G Knepley snes->norm = 0.; 214e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 21519653cdaSPeter Brune 21698b3e84cSPeter Brune /* initialization */ 21719653cdaSPeter Brune 2183a2ae377SPeter Brune if (snes->pc && snes->pcside == PC_LEFT) { 219be95d8f1SBarry Smith ierr = SNESApplyNPC(snes,X,NULL,F);CHKERRQ(ierr); 2203a2ae377SPeter Brune ierr = SNESGetConvergedReason(snes->pc,&reason);CHKERRQ(ierr); 2213a2ae377SPeter Brune if (reason < 0 && reason != SNES_DIVERGED_MAX_IT) { 2223a2ae377SPeter Brune snes->reason = SNES_DIVERGED_INNER; 2233a2ae377SPeter Brune PetscFunctionReturn(0); 2243a2ae377SPeter Brune } 2253a2ae377SPeter Brune ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); 2263a2ae377SPeter Brune } else { 227e4ed7901SPeter Brune if (!snes->vec_func_init_set) { 228f109b39eSPeter Brune ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 2291aa26658SKarl Rupp } else snes->vec_func_init_set = PETSC_FALSE; 230c1c75074SPeter Brune 231f109b39eSPeter Brune ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); 232422a814eSBarry Smith SNESCheckFunctionNorm(snes,fnorm); 2333a2ae377SPeter Brune } 234e4ed7901SPeter Brune fminnorm = fnorm; 23519653cdaSPeter Brune 236e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 237f109b39eSPeter Brune snes->norm = fnorm; 238e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 239a71f0d7dSBarry Smith ierr = SNESLogConvergenceHistory(snes,fnorm,0);CHKERRQ(ierr); 240f109b39eSPeter Brune ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr); 241f109b39eSPeter Brune ierr = (*snes->ops->converged)(snes,0,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); 242a312c225SMatthew G Knepley if (snes->reason) PetscFunctionReturn(0); 243b3c6a99cSPeter Brune SNESNGMRESUpdateSubspace_Private(snes,0,0,F,fnorm,X); 244a312c225SMatthew G Knepley 24519653cdaSPeter Brune k_restart = 1; 24619653cdaSPeter Brune l = 1; 247b3c6a99cSPeter Brune ivec = 0; 24809c08436SPeter Brune for (k=1; k < snes->max_its+1; k++) { 24998b3e84cSPeter Brune /* Computation of x^M */ 250c40d0f55SPeter Brune if (snes->pc && snes->pcside == PC_RIGHT) { 2519f425c49SPeter Brune ierr = VecCopy(X,XM);CHKERRQ(ierr); 252e4ed7901SPeter Brune ierr = SNESSetInitialFunction(snes->pc,F);CHKERRQ(ierr); 25363e7833aSPeter Brune 25463e7833aSPeter Brune ierr = PetscLogEventBegin(SNES_NPCSolve,snes->pc,XM,B,0);CHKERRQ(ierr); 2559f425c49SPeter Brune ierr = SNESSolve(snes->pc,B,XM);CHKERRQ(ierr); 25663e7833aSPeter Brune ierr = PetscLogEventEnd(SNES_NPCSolve,snes->pc,XM,B,0);CHKERRQ(ierr); 25763e7833aSPeter Brune 2588cc86e31SPeter Brune ierr = SNESGetConvergedReason(snes->pc,&reason);CHKERRQ(ierr); 2598cc86e31SPeter Brune if (reason < 0 && reason != SNES_DIVERGED_MAX_IT) { 2608cc86e31SPeter Brune snes->reason = SNES_DIVERGED_INNER; 2618cc86e31SPeter Brune PetscFunctionReturn(0); 2628cc86e31SPeter Brune } 263be95d8f1SBarry Smith ierr = SNESGetNPCFunction(snes,FM,&fMnorm);CHKERRQ(ierr); 2648cc86e31SPeter Brune } else { 265f109b39eSPeter Brune /* no preconditioner -- just take gradient descent with line search */ 266f109b39eSPeter Brune ierr = VecCopy(F,Y);CHKERRQ(ierr); 267e7058c64SPeter Brune ierr = VecCopy(F,FM);CHKERRQ(ierr); 268e7058c64SPeter Brune ierr = VecCopy(X,XM);CHKERRQ(ierr); 2691aa26658SKarl Rupp 270e7058c64SPeter Brune fMnorm = fnorm; 2711aa26658SKarl Rupp 272f1c6b773SPeter Brune ierr = SNESLineSearchApply(snes->linesearch,XM,FM,&fMnorm,Y);CHKERRQ(ierr); 273422a814eSBarry Smith ierr = SNESLineSearchGetReason(snes->linesearch,&lssucceed);CHKERRQ(ierr); 274422a814eSBarry Smith if (lssucceed) { 275f109b39eSPeter Brune if (++snes->numFailures >= snes->maxFailures) { 276f109b39eSPeter Brune snes->reason = SNES_DIVERGED_LINE_SEARCH; 277f109b39eSPeter Brune PetscFunctionReturn(0); 278f109b39eSPeter Brune } 279f109b39eSPeter Brune } 2806634f59bSPeter Brune } 281*23b3e82cSAsbjørn Nilsen Riseth 282b3c6a99cSPeter Brune ierr = SNESNGMRESFormCombinedSolution_Private(snes,ivec,l,XM,FM,fMnorm,X,XA,FA);CHKERRQ(ierr); 28398b3e84cSPeter Brune /* r = F(x) */ 2849f425c49SPeter Brune if (fminnorm > fMnorm) fminnorm = fMnorm; /* the minimum norm is now of F^M */ 28519653cdaSPeter Brune 2869f425c49SPeter Brune /* differences for selection and restart */ 28713a62661SPeter Brune if (ngmres->restart_type == SNES_NGMRES_RESTART_DIFFERENCE || ngmres->select_type == SNES_NGMRES_SELECT_DIFFERENCE) { 288b3c6a99cSPeter Brune ierr = SNESNGMRESNorms_Private(snes,l,X,F,XM,FM,XA,FA,D,&dnorm,&dminnorm,&xMnorm,NULL,&yMnorm,&xAnorm,&fAnorm,&yAnorm);CHKERRQ(ierr); 28913a62661SPeter Brune } else { 290b3c6a99cSPeter Brune ierr = SNESNGMRESNorms_Private(snes,l,X,F,XM,FM,XA,FA,D,NULL,NULL,&xMnorm,NULL,&yMnorm,&xAnorm,&fAnorm,&yAnorm);CHKERRQ(ierr); 29113a62661SPeter Brune } 292422a814eSBarry Smith SNESCheckFunctionNorm(snes,fnorm); 2931aa26658SKarl Rupp 2949f425c49SPeter Brune /* combination (additive) or selection (multiplicative) of the N-GMRES solution */ 295b3c6a99cSPeter Brune ierr = SNESNGMRESSelect_Private(snes,k_restart,XM,FM,xMnorm,fMnorm,yMnorm,XA,FA,xAnorm,fAnorm,yAnorm,dnorm,fminnorm,dminnorm,X,F,Y,&xnorm,&fnorm,&ynorm);CHKERRQ(ierr); 29619653cdaSPeter Brune selectRestart = PETSC_FALSE; 297*23b3e82cSAsbjørn Nilsen Riseth 29813a62661SPeter Brune if (ngmres->restart_type == SNES_NGMRES_RESTART_DIFFERENCE) { 299*23b3e82cSAsbjørn Nilsen Riseth ierr = SNESNGMRESSelectRestart_Private(snes,l,fMnorm,fAnorm,dnorm,fminnorm,dminnorm,&selectRestart);CHKERRQ(ierr); 300*23b3e82cSAsbjørn Nilsen Riseth 30128ed4a04SPeter Brune /* if the restart conditions persist for more than restart_it iterations, restart. */ 3021aa26658SKarl Rupp if (selectRestart) restart_count++; 3031aa26658SKarl Rupp else restart_count = 0; 30413a62661SPeter Brune } else if (ngmres->restart_type == SNES_NGMRES_RESTART_PERIODIC) { 30513a62661SPeter Brune if (k_restart > ngmres->restart_periodic) { 30613a62661SPeter Brune if (ngmres->monitor) ierr = PetscViewerASCIIPrintf(ngmres->monitor,"periodic restart after %D iterations\n",k_restart);CHKERRQ(ierr); 30713a62661SPeter Brune restart_count = ngmres->restart_it; 30813a62661SPeter Brune } 30913a62661SPeter Brune } 310*23b3e82cSAsbjørn Nilsen Riseth 311b3c6a99cSPeter Brune ivec = k_restart % ngmres->msize; /* replace the last used part of the subspace */ 312*23b3e82cSAsbjørn Nilsen Riseth 31328ed4a04SPeter Brune /* restart after restart conditions have persisted for a fixed number of iterations */ 31428ed4a04SPeter Brune if (restart_count >= ngmres->restart_it) { 315dfbf837cSBarry Smith if (ngmres->monitor) { 316dfbf837cSBarry Smith ierr = PetscViewerASCIIPrintf(ngmres->monitor,"Restarted at iteration %d\n",k_restart);CHKERRQ(ierr); 317dfbf837cSBarry Smith } 31828ed4a04SPeter Brune restart_count = 0; 31919653cdaSPeter Brune k_restart = 1; 32019653cdaSPeter Brune l = 1; 321b3c6a99cSPeter Brune ivec = 0; 32298b3e84cSPeter Brune /* q_{00} = nu */ 323fa8c639aSPeter Brune ierr = SNESNGMRESUpdateSubspace_Private(snes,0,0,FM,fMnorm,XM);CHKERRQ(ierr); 324d2e16ddcSPeter Brune } else { 32598b3e84cSPeter Brune /* select the current size of the subspace */ 3261e633543SBarry Smith if (l < ngmres->msize) l++; 32719653cdaSPeter Brune k_restart++; 32898b3e84cSPeter Brune /* place the current entry in the list of previous entries */ 32938774f0aSPeter Brune if (ngmres->candidate) { 33038774f0aSPeter Brune if (fminnorm > fMnorm) fminnorm = fMnorm; 331fa8c639aSPeter Brune ierr = SNESNGMRESUpdateSubspace_Private(snes,ivec,l,FM,fMnorm,XM);CHKERRQ(ierr); 332d2e16ddcSPeter Brune } else { 33338774f0aSPeter Brune if (fminnorm > fnorm) fminnorm = fnorm; 334fa8c639aSPeter Brune ierr = SNESNGMRESUpdateSubspace_Private(snes,ivec,l,F,fnorm,X);CHKERRQ(ierr); 33519653cdaSPeter Brune } 336d2e16ddcSPeter Brune } 33719653cdaSPeter Brune 338e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 339087dfb9eSxuemin snes->iter = k; 340f109b39eSPeter Brune snes->norm = fnorm; 341e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 342a71f0d7dSBarry Smith ierr = SNESLogConvergenceHistory(snes,snes->norm,snes->iter);CHKERRQ(ierr); 3438409ca45SMatthew G Knepley ierr = SNESMonitor(snes,snes->iter,snes->norm);CHKERRQ(ierr); 344b3c6a99cSPeter Brune ierr = (*snes->ops->converged)(snes,snes->iter,0,0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); 345087dfb9eSxuemin if (snes->reason) PetscFunctionReturn(0); 346a312c225SMatthew G Knepley } 347a312c225SMatthew G Knepley snes->reason = SNES_DIVERGED_MAX_IT; 348a312c225SMatthew G Knepley PetscFunctionReturn(0); 349a312c225SMatthew G Knepley } 350a312c225SMatthew G Knepley 35113a62661SPeter Brune #undef __FUNCT__ 352*23b3e82cSAsbjørn Nilsen Riseth #define __FUNCT__ "SNESNGMRESSetRestartFmRise" 353*23b3e82cSAsbjørn Nilsen Riseth /*@ 354*23b3e82cSAsbjørn Nilsen Riseth SNESNGMRESSetRestartFmRise - Increase the restart count if the step x_M increases the residual F_M 355*23b3e82cSAsbjørn Nilsen Riseth 356*23b3e82cSAsbjørn Nilsen Riseth Input Parameters: 357*23b3e82cSAsbjørn Nilsen Riseth + snes - the SNES context. 358*23b3e82cSAsbjørn Nilsen Riseth - flg - boolean value deciding whether to use the option or not 359*23b3e82cSAsbjørn Nilsen Riseth 360*23b3e82cSAsbjørn Nilsen Riseth Options Database: 361*23b3e82cSAsbjørn Nilsen Riseth + -snes_ngmres_restart_fm_rise - Increase the restart count if the step x_M increases the residual F_M 362*23b3e82cSAsbjørn Nilsen Riseth 363*23b3e82cSAsbjørn Nilsen Riseth Level: intermediate 364*23b3e82cSAsbjørn Nilsen Riseth 365*23b3e82cSAsbjørn Nilsen Riseth Notes: 366*23b3e82cSAsbjørn Nilsen Riseth If the proposed step x_M increases the residual F_M, it might be trying to get out of a stagnation area. 367*23b3e82cSAsbjørn Nilsen Riseth To help the solver do that, reset the Krylov subspace whenever F_M increases. 368*23b3e82cSAsbjørn Nilsen Riseth 369*23b3e82cSAsbjørn Nilsen Riseth This option must be used with SNES_NGMRES_RESTART_DIFFERENCE 370*23b3e82cSAsbjørn Nilsen Riseth 371*23b3e82cSAsbjørn Nilsen Riseth The default is FALSE. 372*23b3e82cSAsbjørn Nilsen Riseth .seealso: SNES_NGMRES_RESTART_DIFFERENCE 373*23b3e82cSAsbjørn Nilsen Riseth @*/ 374*23b3e82cSAsbjørn Nilsen Riseth PetscErrorCode SNESNGMRESSetRestartFmRise(SNES snes,PetscBool flg) 375*23b3e82cSAsbjørn Nilsen Riseth { 376*23b3e82cSAsbjørn Nilsen Riseth PetscErrorCode (*f)(SNES,PetscBool); 377*23b3e82cSAsbjørn Nilsen Riseth PetscErrorCode ierr; 378*23b3e82cSAsbjørn Nilsen Riseth 379*23b3e82cSAsbjørn Nilsen Riseth PetscFunctionBegin; 380*23b3e82cSAsbjørn Nilsen Riseth ierr = PetscObjectQueryFunction((PetscObject)snes,"SNESNGMRESSetRestartFmRise_C",&f);CHKERRQ(ierr); 381*23b3e82cSAsbjørn Nilsen Riseth if (f) {ierr = (f)(snes,flg);CHKERRQ(ierr);} 382*23b3e82cSAsbjørn Nilsen Riseth PetscFunctionReturn(0); 383*23b3e82cSAsbjørn Nilsen Riseth } 384*23b3e82cSAsbjørn Nilsen Riseth 385*23b3e82cSAsbjørn Nilsen Riseth #undef __FUNCT__ 386*23b3e82cSAsbjørn Nilsen Riseth #define __FUNCT__ "SNESNGMRESSetRestartFmRise_NGMRES" 387*23b3e82cSAsbjørn Nilsen Riseth PetscErrorCode SNESNGMRESSetRestartFmRise_NGMRES(SNES snes,PetscBool flg) 388*23b3e82cSAsbjørn Nilsen Riseth { 389*23b3e82cSAsbjørn Nilsen Riseth SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 390*23b3e82cSAsbjørn Nilsen Riseth 391*23b3e82cSAsbjørn Nilsen Riseth PetscFunctionBegin; 392*23b3e82cSAsbjørn Nilsen Riseth ngmres->restart_fm_rise = flg; 393*23b3e82cSAsbjørn Nilsen Riseth PetscFunctionReturn(0); 394*23b3e82cSAsbjørn Nilsen Riseth } 395*23b3e82cSAsbjørn Nilsen Riseth 396*23b3e82cSAsbjørn Nilsen Riseth #undef __FUNCT__ 397*23b3e82cSAsbjørn Nilsen Riseth #define __FUNCT__ "SNESNGMRESGetRestartFmRise" 398*23b3e82cSAsbjørn Nilsen Riseth PetscErrorCode SNESNGMRESGetRestartFmRise(SNES snes,PetscBool *flg) 399*23b3e82cSAsbjørn Nilsen Riseth { 400*23b3e82cSAsbjørn Nilsen Riseth PetscErrorCode (*f)(SNES,PetscBool*); 401*23b3e82cSAsbjørn Nilsen Riseth PetscErrorCode ierr; 402*23b3e82cSAsbjørn Nilsen Riseth 403*23b3e82cSAsbjørn Nilsen Riseth PetscFunctionBegin; 404*23b3e82cSAsbjørn Nilsen Riseth ierr = PetscObjectQueryFunction((PetscObject)snes,"SNESNGMRESGetRestartFmRise_C",&f);CHKERRQ(ierr); 405*23b3e82cSAsbjørn Nilsen Riseth if (f) {ierr = (f)(snes,flg);CHKERRQ(ierr);} 406*23b3e82cSAsbjørn Nilsen Riseth PetscFunctionReturn(0); 407*23b3e82cSAsbjørn Nilsen Riseth } 408*23b3e82cSAsbjørn Nilsen Riseth 409*23b3e82cSAsbjørn Nilsen Riseth #undef __FUNCT__ 410*23b3e82cSAsbjørn Nilsen Riseth #define __FUNCT__ "SNESNGMRESGetRestartFmRise_NGMRES" 411*23b3e82cSAsbjørn Nilsen Riseth PetscErrorCode SNESNGMRESGetRestartFmRise_NGMRES(SNES snes,PetscBool *flg) 412*23b3e82cSAsbjørn Nilsen Riseth { 413*23b3e82cSAsbjørn Nilsen Riseth SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 414*23b3e82cSAsbjørn Nilsen Riseth 415*23b3e82cSAsbjørn Nilsen Riseth PetscFunctionBegin; 416*23b3e82cSAsbjørn Nilsen Riseth *flg = ngmres->restart_fm_rise; 417*23b3e82cSAsbjørn Nilsen Riseth PetscFunctionReturn(0); 418*23b3e82cSAsbjørn Nilsen Riseth } 419*23b3e82cSAsbjørn Nilsen Riseth 420*23b3e82cSAsbjørn Nilsen Riseth 421*23b3e82cSAsbjørn Nilsen Riseth #undef __FUNCT__ 42213a62661SPeter Brune #define __FUNCT__ "SNESNGMRESSetRestartType" 42313a62661SPeter Brune /*@ 42413a62661SPeter Brune SNESNGMRESSetRestartType - Sets the restart type for SNESNGMRES. 42513a62661SPeter Brune 42613a62661SPeter Brune Logically Collective on SNES 42713a62661SPeter Brune 42813a62661SPeter Brune Input Parameters: 42913a62661SPeter Brune + snes - the iterative context 43013a62661SPeter Brune - rtype - restart type 43113a62661SPeter Brune 43213a62661SPeter Brune Options Database: 43313a62661SPeter Brune + -snes_ngmres_restart_type<difference,periodic,none> - set the restart type 4340c777b0cSPeter Brune - -snes_ngmres_restart[30] - sets the number of iterations before restart for periodic 43513a62661SPeter Brune 43613a62661SPeter Brune Level: intermediate 43713a62661SPeter Brune 43813a62661SPeter Brune SNESNGMRESRestartTypes: 43913a62661SPeter Brune + SNES_NGMRES_RESTART_NONE - never restart 44013a62661SPeter Brune . SNES_NGMRES_RESTART_DIFFERENCE - restart based upon difference criteria 44113a62661SPeter Brune - SNES_NGMRES_RESTART_PERIODIC - restart after a fixed number of iterations 44213a62661SPeter Brune 44313a62661SPeter Brune Notes: 44413a62661SPeter Brune The default line search used is the L2 line search and it requires two additional function evaluations. 44513a62661SPeter Brune 44613a62661SPeter Brune .keywords: SNES, SNESNGMRES, restart, type, set SNESLineSearch 44713a62661SPeter Brune @*/ 4480adebc6cSBarry Smith PetscErrorCode SNESNGMRESSetRestartType(SNES snes,SNESNGMRESRestartType rtype) 4490adebc6cSBarry Smith { 45013a62661SPeter Brune PetscErrorCode ierr; 4515fd66863SKarl Rupp 45213a62661SPeter Brune PetscFunctionBegin; 45313a62661SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45413a62661SPeter Brune ierr = PetscTryMethod(snes,"SNESNGMRESSetRestartType_C",(SNES,SNESNGMRESRestartType),(snes,rtype));CHKERRQ(ierr); 45513a62661SPeter Brune PetscFunctionReturn(0); 45613a62661SPeter Brune } 45713a62661SPeter Brune 45813a62661SPeter Brune #undef __FUNCT__ 45913a62661SPeter Brune #define __FUNCT__ "SNESNGMRESSetSelectType" 46013a62661SPeter Brune /*@ 46113a62661SPeter Brune SNESNGMRESSetSelectType - Sets the selection type for SNESNGMRES. This determines how the candidate solution and 46213a62661SPeter Brune combined solution are used to create the next iterate. 46313a62661SPeter Brune 46413a62661SPeter Brune Logically Collective on SNES 46513a62661SPeter Brune 46613a62661SPeter Brune Input Parameters: 46713a62661SPeter Brune + snes - the iterative context 46813a62661SPeter Brune - stype - selection type 46913a62661SPeter Brune 47013a62661SPeter Brune Options Database: 47113a62661SPeter Brune . -snes_ngmres_select_type<difference,none,linesearch> 47213a62661SPeter Brune 47313a62661SPeter Brune Level: intermediate 47413a62661SPeter Brune 47513a62661SPeter Brune SNESNGMRESSelectTypes: 47613a62661SPeter Brune + SNES_NGMRES_SELECT_NONE - choose the combined solution all the time 47713a62661SPeter Brune . SNES_NGMRES_SELECT_DIFFERENCE - choose based upon the selection criteria 47813a62661SPeter Brune - SNES_NGMRES_SELECT_LINESEARCH - choose based upon line search combination 47913a62661SPeter Brune 48013a62661SPeter Brune Notes: 48113a62661SPeter Brune The default line search used is the L2 line search and it requires two additional function evaluations. 48213a62661SPeter Brune 48313a62661SPeter Brune .keywords: SNES, SNESNGMRES, selection, type, set SNESLineSearch 48413a62661SPeter Brune @*/ 4850adebc6cSBarry Smith PetscErrorCode SNESNGMRESSetSelectType(SNES snes,SNESNGMRESSelectType stype) 4860adebc6cSBarry Smith { 48713a62661SPeter Brune PetscErrorCode ierr; 4885fd66863SKarl Rupp 48913a62661SPeter Brune PetscFunctionBegin; 49013a62661SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49113a62661SPeter Brune ierr = PetscTryMethod(snes,"SNESNGMRESSetSelectType_C",(SNES,SNESNGMRESSelectType),(snes,stype));CHKERRQ(ierr); 49213a62661SPeter Brune PetscFunctionReturn(0); 49313a62661SPeter Brune } 49413a62661SPeter Brune 49513a62661SPeter Brune #undef __FUNCT__ 49613a62661SPeter Brune #define __FUNCT__ "SNESNGMRESSetSelectType_NGMRES" 4970adebc6cSBarry Smith PetscErrorCode SNESNGMRESSetSelectType_NGMRES(SNES snes,SNESNGMRESSelectType stype) 4980adebc6cSBarry Smith { 49913a62661SPeter Brune SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 5005fd66863SKarl Rupp 50113a62661SPeter Brune PetscFunctionBegin; 50213a62661SPeter Brune ngmres->select_type = stype; 50313a62661SPeter Brune PetscFunctionReturn(0); 50413a62661SPeter Brune } 50513a62661SPeter Brune 50613a62661SPeter Brune #undef __FUNCT__ 50713a62661SPeter Brune #define __FUNCT__ "SNESNGMRESSetRestartType_NGMRES" 5080adebc6cSBarry Smith PetscErrorCode SNESNGMRESSetRestartType_NGMRES(SNES snes,SNESNGMRESRestartType rtype) 5090adebc6cSBarry Smith { 51013a62661SPeter Brune SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 5115fd66863SKarl Rupp 51213a62661SPeter Brune PetscFunctionBegin; 51313a62661SPeter Brune ngmres->restart_type = rtype; 51413a62661SPeter Brune PetscFunctionReturn(0); 51513a62661SPeter Brune } 51613a62661SPeter Brune 517dfbf837cSBarry Smith /*MC 5181867fe5bSPeter Brune SNESNGMRES - The Nonlinear Generalized Minimum Residual method. 519a312c225SMatthew G Knepley 520dfbf837cSBarry Smith Level: beginner 521dfbf837cSBarry Smith 5221867fe5bSPeter Brune Options Database: 52313a62661SPeter Brune + -snes_ngmres_select_type<difference,none,linesearch> - choose the select between candidate and combined solution 52438774f0aSPeter Brune . -snes_ngmres_restart_type<difference,none,periodic> - choose the restart conditions 52538774f0aSPeter Brune . -snes_ngmres_candidate - Use NGMRES variant which combines candidate solutions instead of actual solutions 52613a62661SPeter Brune . -snes_ngmres_m - Number of stored previous solutions and residuals 52713a62661SPeter Brune . -snes_ngmres_restart_it - Number of iterations the restart conditions hold before restart 52813a62661SPeter Brune . -snes_ngmres_gammaA - Residual tolerance for solution select between the candidate and combination 52913a62661SPeter Brune . -snes_ngmres_gammaC - Residual tolerance for restart 53013a62661SPeter Brune . -snes_ngmres_epsilonB - Difference tolerance between subsequent solutions triggering restart 53113a62661SPeter Brune . -snes_ngmres_deltaB - Difference tolerance between residuals triggering restart 532*23b3e82cSAsbjørn Nilsen Riseth . -snes_ngmres_restart_fm_rise - Restart on residual rise from x_M step 53313a62661SPeter Brune . -snes_ngmres_monitor - Prints relevant information about the ngmres iteration 5345c3e6ab7SPeter Brune . -snes_linesearch_type <basic,l2,cp> - Line search type used for the default smoother 53513a62661SPeter Brune - -additive_snes_linesearch_type - linesearch type used to select between the candidate and combined solution with additive select type 5361867fe5bSPeter Brune 5371867fe5bSPeter Brune Notes: 5381867fe5bSPeter Brune 5391867fe5bSPeter Brune The N-GMRES method combines m previous solutions into a minimum-residual solution by solving a small linearized 5401867fe5bSPeter Brune optimization problem at each iteration. 5411867fe5bSPeter Brune 5421867fe5bSPeter Brune References: 5431867fe5bSPeter Brune 544dfbf837cSBarry Smith "Krylov Subspace Acceleration of Nonlinear Multigrid with Application to Recirculating Flows", C. W. Oosterlee and T. Washio, 545dfbf837cSBarry Smith SIAM Journal on Scientific Computing, 21(5), 2000. 546dfbf837cSBarry Smith 547dfbf837cSBarry Smith .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types) 548dfbf837cSBarry Smith M*/ 549a312c225SMatthew G Knepley 550a312c225SMatthew G Knepley #undef __FUNCT__ 551a312c225SMatthew G Knepley #define __FUNCT__ "SNESCreate_NGMRES" 5528cc058d9SJed Brown PETSC_EXTERN PetscErrorCode SNESCreate_NGMRES(SNES snes) 553a312c225SMatthew G Knepley { 554a312c225SMatthew G Knepley SNES_NGMRES *ngmres; 555a312c225SMatthew G Knepley PetscErrorCode ierr; 556a312c225SMatthew G Knepley 557a312c225SMatthew G Knepley PetscFunctionBegin; 558a312c225SMatthew G Knepley snes->ops->destroy = SNESDestroy_NGMRES; 559a312c225SMatthew G Knepley snes->ops->setup = SNESSetUp_NGMRES; 560a312c225SMatthew G Knepley snes->ops->setfromoptions = SNESSetFromOptions_NGMRES; 561a312c225SMatthew G Knepley snes->ops->view = SNESView_NGMRES; 562a312c225SMatthew G Knepley snes->ops->solve = SNESSolve_NGMRES; 563a312c225SMatthew G Knepley snes->ops->reset = SNESReset_NGMRES; 564a312c225SMatthew G Knepley 56542f4f86dSBarry Smith snes->usespc = PETSC_TRUE; 5662c155ee1SBarry Smith snes->usesksp = PETSC_FALSE; 56746159c86SPeter Brune snes->pcside = PC_RIGHT; 5682c155ee1SBarry Smith 569b00a9115SJed Brown ierr = PetscNewLog(snes,&ngmres);CHKERRQ(ierr); 570a312c225SMatthew G Knepley snes->data = (void*) ngmres; 571d2e16ddcSPeter Brune ngmres->msize = 30; 57219653cdaSPeter Brune 57388976e71SPeter Brune if (!snes->tolerancesset) { 5740e444f03SPeter Brune snes->max_funcs = 30000; 5750e444f03SPeter Brune snes->max_its = 10000; 57688976e71SPeter Brune } 5770e444f03SPeter Brune 57838774f0aSPeter Brune ngmres->candidate = PETSC_FALSE; 579d2e16ddcSPeter Brune 5800298fd71SBarry Smith ngmres->additive_linesearch = NULL; 581077c4231SPeter Brune ngmres->approxfunc = PETSC_FALSE; 58228ed4a04SPeter Brune ngmres->restart_it = 2; 58313a62661SPeter Brune ngmres->restart_periodic = 30; 584f109b39eSPeter Brune ngmres->gammaA = 2.0; 585f109b39eSPeter Brune ngmres->gammaC = 2.0; 586cac108bcSPeter Brune ngmres->deltaB = 0.9; 587cac108bcSPeter Brune ngmres->epsilonB = 0.1; 588*23b3e82cSAsbjørn Nilsen Riseth ngmres->restart_fm_rise = PETSC_FALSE; 589e7058c64SPeter Brune 59013a62661SPeter Brune ngmres->restart_type = SNES_NGMRES_RESTART_DIFFERENCE; 59113a62661SPeter Brune ngmres->select_type = SNES_NGMRES_SELECT_DIFFERENCE; 59213a62661SPeter Brune 593bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESNGMRESSetSelectType_C",SNESNGMRESSetSelectType_NGMRES);CHKERRQ(ierr); 594bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESNGMRESSetRestartType_C",SNESNGMRESSetRestartType_NGMRES);CHKERRQ(ierr); 595*23b3e82cSAsbjørn Nilsen Riseth ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESNGMRESSetRestartFmRise_C",SNESNGMRESSetRestartFmRise_NGMRES);CHKERRQ(ierr); 596*23b3e82cSAsbjørn Nilsen Riseth ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESNGMRESGetRestartFmRise_C",SNESNGMRESGetRestartFmRise_NGMRES);CHKERRQ(ierr); 597a312c225SMatthew G Knepley PetscFunctionReturn(0); 598a312c225SMatthew G Knepley } 599