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 PetscErrorCode SNESReset_NGMRES(SNES snes) 9a312c225SMatthew G Knepley { 10a312c225SMatthew G Knepley SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 11a312c225SMatthew G Knepley PetscErrorCode ierr; 12a312c225SMatthew G Knepley 13a312c225SMatthew G Knepley PetscFunctionBegin; 14f109b39eSPeter Brune ierr = VecDestroyVecs(ngmres->msize,&ngmres->Fdot);CHKERRQ(ierr); 15f109b39eSPeter Brune ierr = VecDestroyVecs(ngmres->msize,&ngmres->Xdot);CHKERRQ(ierr); 16f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&ngmres->additive_linesearch);CHKERRQ(ierr); 17a312c225SMatthew G Knepley PetscFunctionReturn(0); 18a312c225SMatthew G Knepley } 19a312c225SMatthew G Knepley 20a312c225SMatthew G Knepley PetscErrorCode SNESDestroy_NGMRES(SNES snes) 21a312c225SMatthew G Knepley { 22a312c225SMatthew G Knepley PetscErrorCode ierr; 2378440776SJed Brown SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 24a312c225SMatthew G Knepley 25a312c225SMatthew G Knepley PetscFunctionBegin; 26a312c225SMatthew G Knepley ierr = SNESReset_NGMRES(snes);CHKERRQ(ierr); 27f109b39eSPeter Brune ierr = PetscFree5(ngmres->h,ngmres->beta,ngmres->xi,ngmres->fnorms,ngmres->q);CHKERRQ(ierr); 2819653cdaSPeter Brune ierr = PetscFree(ngmres->s);CHKERRQ(ierr); 2918aa0c0cSPeter Brune ierr = PetscFree(ngmres->xnorms);CHKERRQ(ierr); 30dd63322aSSatish Balay #if defined(PETSC_USE_COMPLEX) 3122d28d08SBarry Smith ierr = PetscFree(ngmres->rwork);CHKERRQ(ierr); 3219653cdaSPeter Brune #endif 3322d28d08SBarry Smith ierr = PetscFree(ngmres->work);CHKERRQ(ierr); 3422d28d08SBarry Smith ierr = PetscFree(snes->data);CHKERRQ(ierr); 35a312c225SMatthew G Knepley PetscFunctionReturn(0); 36a312c225SMatthew G Knepley } 37a312c225SMatthew G Knepley 38a312c225SMatthew G Knepley PetscErrorCode SNESSetUp_NGMRES(SNES snes) 39a312c225SMatthew G Knepley { 40a312c225SMatthew G Knepley SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 41e7058c64SPeter Brune const char *optionsprefix; 4219653cdaSPeter Brune PetscInt msize,hsize; 43a312c225SMatthew G Knepley PetscErrorCode ierr; 44fced5a79SAsbjørn Nilsen Riseth DM dm; 45a312c225SMatthew G Knepley 46a312c225SMatthew G Knepley PetscFunctionBegin; 47efd4aadfSBarry Smith if (snes->npc && snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_UNPRECONDITIONED) { 4846159c86SPeter Brune SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"SNESNGMRES does not support left preconditioning with unpreconditioned function"); 4946159c86SPeter Brune } 50efd4aadfSBarry Smith if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_DEFAULT) snes->functype = SNES_FUNCTION_PRECONDITIONED; 51fa0ddf94SBarry Smith ierr = SNESSetWorkVecs(snes,5);CHKERRQ(ierr); 52fced5a79SAsbjørn Nilsen Riseth 53fced5a79SAsbjørn Nilsen Riseth if (!snes->vec_sol) { 54fced5a79SAsbjørn Nilsen Riseth ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 55fced5a79SAsbjørn Nilsen Riseth ierr = DMCreateGlobalVector(dm,&snes->vec_sol);CHKERRQ(ierr); 56fced5a79SAsbjørn Nilsen Riseth } 57fced5a79SAsbjørn Nilsen Riseth 5878440776SJed Brown if (!ngmres->Xdot) {ierr = VecDuplicateVecs(snes->vec_sol,ngmres->msize,&ngmres->Xdot);CHKERRQ(ierr);} 5978440776SJed Brown if (!ngmres->Fdot) {ierr = VecDuplicateVecs(snes->vec_sol,ngmres->msize,&ngmres->Fdot);CHKERRQ(ierr);} 6078440776SJed Brown if (!ngmres->setup_called) { 61087dfb9eSxuemin msize = ngmres->msize; /* restart size */ 6219653cdaSPeter Brune hsize = msize * msize; 63087dfb9eSxuemin 6498b3e84cSPeter Brune /* explicit least squares minimization solve */ 65dcca6d9dSJed Brown ierr = PetscMalloc5(hsize,&ngmres->h, msize,&ngmres->beta, msize,&ngmres->xi, msize,&ngmres->fnorms, hsize,&ngmres->q);CHKERRQ(ierr); 66785e854fSJed Brown ierr = PetscMalloc1(msize,&ngmres->xnorms);CHKERRQ(ierr); 6719653cdaSPeter Brune ngmres->nrhs = 1; 6819653cdaSPeter Brune ngmres->lda = msize; 6919653cdaSPeter Brune ngmres->ldb = msize; 70785e854fSJed Brown ierr = PetscMalloc1(msize,&ngmres->s);CHKERRQ(ierr); 7119653cdaSPeter Brune ierr = PetscMemzero(ngmres->h, hsize*sizeof(PetscScalar));CHKERRQ(ierr); 7219653cdaSPeter Brune ierr = PetscMemzero(ngmres->q, hsize*sizeof(PetscScalar));CHKERRQ(ierr); 7319653cdaSPeter Brune ierr = PetscMemzero(ngmres->xi, msize*sizeof(PetscScalar));CHKERRQ(ierr); 7419653cdaSPeter Brune ierr = PetscMemzero(ngmres->beta,msize*sizeof(PetscScalar));CHKERRQ(ierr); 7519653cdaSPeter Brune ngmres->lwork = 12*msize; 76dd63322aSSatish Balay #if defined(PETSC_USE_COMPLEX) 77854ce69bSBarry Smith ierr = PetscMalloc1(ngmres->lwork,&ngmres->rwork);CHKERRQ(ierr); 7819653cdaSPeter Brune #endif 79854ce69bSBarry Smith ierr = PetscMalloc1(ngmres->lwork,&ngmres->work);CHKERRQ(ierr); 8078440776SJed Brown } 81e7058c64SPeter Brune 82e7058c64SPeter Brune /* linesearch setup */ 83e7058c64SPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 84e7058c64SPeter Brune 8513a62661SPeter Brune if (ngmres->select_type == SNES_NGMRES_SELECT_LINESEARCH) { 86ce94432eSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes),&ngmres->additive_linesearch);CHKERRQ(ierr); 87f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(ngmres->additive_linesearch,snes);CHKERRQ(ierr); 881a4f838cSPeter Brune ierr = SNESLineSearchSetType(ngmres->additive_linesearch,SNESLINESEARCHL2);CHKERRQ(ierr); 89f1c6b773SPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(ngmres->additive_linesearch,"additive_");CHKERRQ(ierr); 90f1c6b773SPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(ngmres->additive_linesearch,optionsprefix);CHKERRQ(ierr); 91f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(ngmres->additive_linesearch);CHKERRQ(ierr); 92e7058c64SPeter Brune } 93e7058c64SPeter Brune 9478440776SJed Brown ngmres->setup_called = PETSC_TRUE; 95a312c225SMatthew G Knepley PetscFunctionReturn(0); 96a312c225SMatthew G Knepley } 97a312c225SMatthew G Knepley 984416b707SBarry Smith PetscErrorCode SNESSetFromOptions_NGMRES(PetscOptionItems *PetscOptionsObject,SNES snes) 99a312c225SMatthew G Knepley { 100a312c225SMatthew G Knepley SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 101a312c225SMatthew G Knepley PetscErrorCode ierr; 10294ae4db5SBarry Smith PetscBool debug = PETSC_FALSE; 1030adebc6cSBarry Smith 104a312c225SMatthew G Knepley PetscFunctionBegin; 105e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"SNES NGMRES options");CHKERRQ(ierr); 10613a62661SPeter Brune ierr = PetscOptionsEnum("-snes_ngmres_select_type","Select type","SNESNGMRESSetSelectType",SNESNGMRESSelectTypes, 1070298fd71SBarry Smith (PetscEnum)ngmres->select_type,(PetscEnum*)&ngmres->select_type,NULL);CHKERRQ(ierr); 10813a62661SPeter Brune ierr = PetscOptionsEnum("-snes_ngmres_restart_type","Restart type","SNESNGMRESSetRestartType",SNESNGMRESRestartTypes, 1090298fd71SBarry Smith (PetscEnum)ngmres->restart_type,(PetscEnum*)&ngmres->restart_type,NULL);CHKERRQ(ierr); 1100298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ngmres_candidate", "Use candidate storage", "SNES",ngmres->candidate,&ngmres->candidate,NULL);CHKERRQ(ierr); 111077c4231SPeter Brune ierr = PetscOptionsBool("-snes_ngmres_approxfunc","Linearly approximate the function", "SNES",ngmres->approxfunc,&ngmres->approxfunc,NULL);CHKERRQ(ierr); 1120298fd71SBarry Smith ierr = PetscOptionsInt("-snes_ngmres_m", "Number of directions", "SNES",ngmres->msize,&ngmres->msize,NULL);CHKERRQ(ierr); 1130298fd71SBarry Smith ierr = PetscOptionsInt("-snes_ngmres_restart", "Iterations before forced restart", "SNES",ngmres->restart_periodic,&ngmres->restart_periodic,NULL);CHKERRQ(ierr); 1140298fd71SBarry Smith ierr = PetscOptionsInt("-snes_ngmres_restart_it", "Tolerance iterations before restart","SNES",ngmres->restart_it,&ngmres->restart_it,NULL);CHKERRQ(ierr); 1150298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ngmres_monitor", "Monitor actions of NGMRES", "SNES",ngmres->monitor ? PETSC_TRUE : PETSC_FALSE,&debug,NULL);CHKERRQ(ierr); 116dfbf837cSBarry Smith if (debug) { 117ce94432eSBarry Smith ngmres->monitor = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 118dfbf837cSBarry Smith } 1190298fd71SBarry Smith ierr = PetscOptionsReal("-snes_ngmres_gammaA", "Residual selection constant", "SNES",ngmres->gammaA,&ngmres->gammaA,NULL);CHKERRQ(ierr); 1200298fd71SBarry Smith ierr = PetscOptionsReal("-snes_ngmres_gammaC", "Residual restart constant", "SNES",ngmres->gammaC,&ngmres->gammaC,NULL);CHKERRQ(ierr); 1210298fd71SBarry Smith ierr = PetscOptionsReal("-snes_ngmres_epsilonB", "Difference selection constant", "SNES",ngmres->epsilonB,&ngmres->epsilonB,NULL);CHKERRQ(ierr); 1220298fd71SBarry Smith ierr = PetscOptionsReal("-snes_ngmres_deltaB", "Difference residual selection constant", "SNES",ngmres->deltaB,&ngmres->deltaB,NULL);CHKERRQ(ierr); 1230298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ngmres_single_reduction", "Aggregate reductions", "SNES",ngmres->singlereduction,&ngmres->singlereduction,NULL);CHKERRQ(ierr); 12423b3e82cSAsbjø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); 125a312c225SMatthew G Knepley ierr = PetscOptionsTail();CHKERRQ(ierr); 1266a7cf640SPeter Brune if ((ngmres->gammaA > ngmres->gammaC) && (ngmres->gammaC > 2.)) ngmres->gammaC = ngmres->gammaA; 127a312c225SMatthew G Knepley PetscFunctionReturn(0); 128a312c225SMatthew G Knepley } 129a312c225SMatthew G Knepley 130a312c225SMatthew G Knepley PetscErrorCode SNESView_NGMRES(SNES snes,PetscViewer viewer) 131a312c225SMatthew G Knepley { 132a312c225SMatthew G Knepley SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 133a312c225SMatthew G Knepley PetscBool iascii; 134a312c225SMatthew G Knepley PetscErrorCode ierr; 135a312c225SMatthew G Knepley 136a312c225SMatthew G Knepley PetscFunctionBegin; 137251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 138a312c225SMatthew G Knepley if (iascii) { 139f109b39eSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," Number of stored past updates: %d\n", ngmres->msize);CHKERRQ(ierr); 140f109b39eSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," Residual selection: gammaA=%1.0e, gammaC=%1.0e\n",ngmres->gammaA,ngmres->gammaC);CHKERRQ(ierr); 141f109b39eSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," Difference restart: epsilonB=%1.0e, deltaB=%1.0e\n",ngmres->epsilonB,ngmres->deltaB);CHKERRQ(ierr); 14223b3e82cSAsbjørn Nilsen Riseth ierr = PetscViewerASCIIPrintf(viewer," Restart on F_M residual increase: %s\n",ngmres->restart_fm_rise?"TRUE":"FALSE");CHKERRQ(ierr); 143a312c225SMatthew G Knepley } 144a312c225SMatthew G Knepley PetscFunctionReturn(0); 145a312c225SMatthew G Knepley } 146a312c225SMatthew G Knepley 147a312c225SMatthew G Knepley PetscErrorCode SNESSolve_NGMRES(SNES snes) 148a312c225SMatthew G Knepley { 149087dfb9eSxuemin SNES_NGMRES *ngmres = (SNES_NGMRES*) snes->data; 15098b3e84cSPeter Brune /* present solution, residual, and preconditioned residual */ 1519f425c49SPeter Brune Vec X,F,B,D,Y; 152f109b39eSPeter Brune 153f109b39eSPeter Brune /* candidate linear combination answers */ 154ddd40ce5SPeter Brune Vec XA,FA,XM,FM; 15519653cdaSPeter Brune 15698b3e84cSPeter Brune /* coefficients and RHS to the minimization problem */ 15718aa0c0cSPeter Brune PetscReal fnorm,fMnorm,fAnorm; 158b3c6a99cSPeter Brune PetscReal xnorm,xMnorm,xAnorm; 159b3c6a99cSPeter Brune PetscReal ynorm,yMnorm,yAnorm; 16038774f0aSPeter Brune PetscInt k,k_restart,l,ivec,restart_count = 0; 16119653cdaSPeter Brune 16298b3e84cSPeter Brune /* solution selection data */ 16338774f0aSPeter Brune PetscBool selectRestart; 16461ba4676SBarry Smith /* 16561ba4676SBarry Smith These two variables are initialized to prevent compilers/analyzers from producing false warnings about these variables being passed 16661ba4676SBarry Smith to SNESNGMRESSelect_Private() without being set when SNES_NGMRES_RESTART_DIFFERENCE, the values are not used in the subroutines in that case 16761ba4676SBarry Smith so the code is correct as written. 16861ba4676SBarry Smith */ 16961ba4676SBarry Smith PetscReal dnorm = 0.0,dminnorm = 0.0; 170b3c6a99cSPeter Brune PetscReal fminnorm; 17119653cdaSPeter Brune 1721e633543SBarry Smith SNESConvergedReason reason; 173422a814eSBarry Smith SNESLineSearchReason lssucceed; 174a312c225SMatthew G Knepley PetscErrorCode ierr; 175a312c225SMatthew G Knepley 176a312c225SMatthew G Knepley PetscFunctionBegin; 1776c4ed002SBarry Smith if (snes->xl || snes->xu || snes->ops->computevariablebounds) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE, "SNES solver %s does not support bounds", ((PetscObject)snes)->type_name); 178c579b300SPatrick Farrell 179fffbeea8SBarry Smith ierr = PetscCitationsRegister(SNESCitation,&SNEScite);CHKERRQ(ierr); 18098b3e84cSPeter Brune /* variable initialization */ 181a312c225SMatthew G Knepley snes->reason = SNES_CONVERGED_ITERATING; 182f109b39eSPeter Brune X = snes->vec_sol; 183f109b39eSPeter Brune F = snes->vec_func; 184f109b39eSPeter Brune B = snes->vec_rhs; 185f109b39eSPeter Brune XA = snes->vec_sol_update; 186f109b39eSPeter Brune FA = snes->work[0]; 187f109b39eSPeter Brune D = snes->work[1]; 188f109b39eSPeter Brune 189f109b39eSPeter Brune /* work for the line search */ 190f109b39eSPeter Brune Y = snes->work[2]; 1919f425c49SPeter Brune XM = snes->work[3]; 1929f425c49SPeter Brune FM = snes->work[4]; 193a312c225SMatthew G Knepley 194e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 195a312c225SMatthew G Knepley snes->iter = 0; 196a312c225SMatthew G Knepley snes->norm = 0.; 197e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 19819653cdaSPeter Brune 19998b3e84cSPeter Brune /* initialization */ 20019653cdaSPeter Brune 201efd4aadfSBarry Smith if (snes->npc && snes->npcside== PC_LEFT) { 202be95d8f1SBarry Smith ierr = SNESApplyNPC(snes,X,NULL,F);CHKERRQ(ierr); 203efd4aadfSBarry Smith ierr = SNESGetConvergedReason(snes->npc,&reason);CHKERRQ(ierr); 2043a2ae377SPeter Brune if (reason < 0 && reason != SNES_DIVERGED_MAX_IT) { 2053a2ae377SPeter Brune snes->reason = SNES_DIVERGED_INNER; 2063a2ae377SPeter Brune PetscFunctionReturn(0); 2073a2ae377SPeter Brune } 2083a2ae377SPeter Brune ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); 2093a2ae377SPeter Brune } else { 210e4ed7901SPeter Brune if (!snes->vec_func_init_set) { 211f109b39eSPeter Brune ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 2121aa26658SKarl Rupp } else snes->vec_func_init_set = PETSC_FALSE; 213c1c75074SPeter Brune 214f109b39eSPeter Brune ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); 215422a814eSBarry Smith SNESCheckFunctionNorm(snes,fnorm); 2163a2ae377SPeter Brune } 217e4ed7901SPeter Brune fminnorm = fnorm; 21819653cdaSPeter Brune 219e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 220f109b39eSPeter Brune snes->norm = fnorm; 221e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 222a71f0d7dSBarry Smith ierr = SNESLogConvergenceHistory(snes,fnorm,0);CHKERRQ(ierr); 223f109b39eSPeter Brune ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr); 224f109b39eSPeter Brune ierr = (*snes->ops->converged)(snes,0,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); 225a312c225SMatthew G Knepley if (snes->reason) PetscFunctionReturn(0); 226b3c6a99cSPeter Brune SNESNGMRESUpdateSubspace_Private(snes,0,0,F,fnorm,X); 227a312c225SMatthew G Knepley 22819653cdaSPeter Brune k_restart = 1; 22919653cdaSPeter Brune l = 1; 230b3c6a99cSPeter Brune ivec = 0; 23109c08436SPeter Brune for (k=1; k < snes->max_its+1; k++) { 23298b3e84cSPeter Brune /* Computation of x^M */ 233efd4aadfSBarry Smith if (snes->npc && snes->npcside== PC_RIGHT) { 2349f425c49SPeter Brune ierr = VecCopy(X,XM);CHKERRQ(ierr); 235efd4aadfSBarry Smith ierr = SNESSetInitialFunction(snes->npc,F);CHKERRQ(ierr); 23663e7833aSPeter Brune 237efd4aadfSBarry Smith ierr = PetscLogEventBegin(SNES_NPCSolve,snes->npc,XM,B,0);CHKERRQ(ierr); 238efd4aadfSBarry Smith ierr = SNESSolve(snes->npc,B,XM);CHKERRQ(ierr); 239efd4aadfSBarry Smith ierr = PetscLogEventEnd(SNES_NPCSolve,snes->npc,XM,B,0);CHKERRQ(ierr); 24063e7833aSPeter Brune 241efd4aadfSBarry Smith ierr = SNESGetConvergedReason(snes->npc,&reason);CHKERRQ(ierr); 2428cc86e31SPeter Brune if (reason < 0 && reason != SNES_DIVERGED_MAX_IT) { 2438cc86e31SPeter Brune snes->reason = SNES_DIVERGED_INNER; 2448cc86e31SPeter Brune PetscFunctionReturn(0); 2458cc86e31SPeter Brune } 246be95d8f1SBarry Smith ierr = SNESGetNPCFunction(snes,FM,&fMnorm);CHKERRQ(ierr); 2478cc86e31SPeter Brune } else { 248f109b39eSPeter Brune /* no preconditioner -- just take gradient descent with line search */ 249f109b39eSPeter Brune ierr = VecCopy(F,Y);CHKERRQ(ierr); 250e7058c64SPeter Brune ierr = VecCopy(F,FM);CHKERRQ(ierr); 251e7058c64SPeter Brune ierr = VecCopy(X,XM);CHKERRQ(ierr); 2521aa26658SKarl Rupp 253e7058c64SPeter Brune fMnorm = fnorm; 2541aa26658SKarl Rupp 255f1c6b773SPeter Brune ierr = SNESLineSearchApply(snes->linesearch,XM,FM,&fMnorm,Y);CHKERRQ(ierr); 256422a814eSBarry Smith ierr = SNESLineSearchGetReason(snes->linesearch,&lssucceed);CHKERRQ(ierr); 257422a814eSBarry Smith if (lssucceed) { 258f109b39eSPeter Brune if (++snes->numFailures >= snes->maxFailures) { 259f109b39eSPeter Brune snes->reason = SNES_DIVERGED_LINE_SEARCH; 260f109b39eSPeter Brune PetscFunctionReturn(0); 261f109b39eSPeter Brune } 262f109b39eSPeter Brune } 2636634f59bSPeter Brune } 26423b3e82cSAsbjørn Nilsen Riseth 265b3c6a99cSPeter Brune ierr = SNESNGMRESFormCombinedSolution_Private(snes,ivec,l,XM,FM,fMnorm,X,XA,FA);CHKERRQ(ierr); 26698b3e84cSPeter Brune /* r = F(x) */ 2679f425c49SPeter Brune if (fminnorm > fMnorm) fminnorm = fMnorm; /* the minimum norm is now of F^M */ 26819653cdaSPeter Brune 2699f425c49SPeter Brune /* differences for selection and restart */ 27013a62661SPeter Brune if (ngmres->restart_type == SNES_NGMRES_RESTART_DIFFERENCE || ngmres->select_type == SNES_NGMRES_SELECT_DIFFERENCE) { 271b3c6a99cSPeter Brune ierr = SNESNGMRESNorms_Private(snes,l,X,F,XM,FM,XA,FA,D,&dnorm,&dminnorm,&xMnorm,NULL,&yMnorm,&xAnorm,&fAnorm,&yAnorm);CHKERRQ(ierr); 27213a62661SPeter Brune } else { 273b3c6a99cSPeter Brune ierr = SNESNGMRESNorms_Private(snes,l,X,F,XM,FM,XA,FA,D,NULL,NULL,&xMnorm,NULL,&yMnorm,&xAnorm,&fAnorm,&yAnorm);CHKERRQ(ierr); 27413a62661SPeter Brune } 275422a814eSBarry Smith SNESCheckFunctionNorm(snes,fnorm); 2761aa26658SKarl Rupp 2779f425c49SPeter Brune /* combination (additive) or selection (multiplicative) of the N-GMRES solution */ 278b3c6a99cSPeter 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); 27919653cdaSPeter Brune selectRestart = PETSC_FALSE; 28023b3e82cSAsbjørn Nilsen Riseth 28113a62661SPeter Brune if (ngmres->restart_type == SNES_NGMRES_RESTART_DIFFERENCE) { 28223b3e82cSAsbjørn Nilsen Riseth ierr = SNESNGMRESSelectRestart_Private(snes,l,fMnorm,fAnorm,dnorm,fminnorm,dminnorm,&selectRestart);CHKERRQ(ierr); 28323b3e82cSAsbjørn Nilsen Riseth 28428ed4a04SPeter Brune /* if the restart conditions persist for more than restart_it iterations, restart. */ 2851aa26658SKarl Rupp if (selectRestart) restart_count++; 2861aa26658SKarl Rupp else restart_count = 0; 28713a62661SPeter Brune } else if (ngmres->restart_type == SNES_NGMRES_RESTART_PERIODIC) { 28813a62661SPeter Brune if (k_restart > ngmres->restart_periodic) { 28913a62661SPeter Brune if (ngmres->monitor) ierr = PetscViewerASCIIPrintf(ngmres->monitor,"periodic restart after %D iterations\n",k_restart);CHKERRQ(ierr); 29013a62661SPeter Brune restart_count = ngmres->restart_it; 29113a62661SPeter Brune } 29213a62661SPeter Brune } 29323b3e82cSAsbjørn Nilsen Riseth 294b3c6a99cSPeter Brune ivec = k_restart % ngmres->msize; /* replace the last used part of the subspace */ 29523b3e82cSAsbjørn Nilsen Riseth 29628ed4a04SPeter Brune /* restart after restart conditions have persisted for a fixed number of iterations */ 29728ed4a04SPeter Brune if (restart_count >= ngmres->restart_it) { 298dfbf837cSBarry Smith if (ngmres->monitor) { 299dfbf837cSBarry Smith ierr = PetscViewerASCIIPrintf(ngmres->monitor,"Restarted at iteration %d\n",k_restart);CHKERRQ(ierr); 300dfbf837cSBarry Smith } 30128ed4a04SPeter Brune restart_count = 0; 30219653cdaSPeter Brune k_restart = 1; 30319653cdaSPeter Brune l = 1; 304b3c6a99cSPeter Brune ivec = 0; 30598b3e84cSPeter Brune /* q_{00} = nu */ 306fa8c639aSPeter Brune ierr = SNESNGMRESUpdateSubspace_Private(snes,0,0,FM,fMnorm,XM);CHKERRQ(ierr); 307d2e16ddcSPeter Brune } else { 30898b3e84cSPeter Brune /* select the current size of the subspace */ 3091e633543SBarry Smith if (l < ngmres->msize) l++; 31019653cdaSPeter Brune k_restart++; 31198b3e84cSPeter Brune /* place the current entry in the list of previous entries */ 31238774f0aSPeter Brune if (ngmres->candidate) { 31338774f0aSPeter Brune if (fminnorm > fMnorm) fminnorm = fMnorm; 314fa8c639aSPeter Brune ierr = SNESNGMRESUpdateSubspace_Private(snes,ivec,l,FM,fMnorm,XM);CHKERRQ(ierr); 315d2e16ddcSPeter Brune } else { 31638774f0aSPeter Brune if (fminnorm > fnorm) fminnorm = fnorm; 317fa8c639aSPeter Brune ierr = SNESNGMRESUpdateSubspace_Private(snes,ivec,l,F,fnorm,X);CHKERRQ(ierr); 31819653cdaSPeter Brune } 319d2e16ddcSPeter Brune } 32019653cdaSPeter Brune 321e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 322087dfb9eSxuemin snes->iter = k; 323f109b39eSPeter Brune snes->norm = fnorm; 324e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 325a71f0d7dSBarry Smith ierr = SNESLogConvergenceHistory(snes,snes->norm,snes->iter);CHKERRQ(ierr); 3268409ca45SMatthew G Knepley ierr = SNESMonitor(snes,snes->iter,snes->norm);CHKERRQ(ierr); 327b3c6a99cSPeter Brune ierr = (*snes->ops->converged)(snes,snes->iter,0,0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); 328087dfb9eSxuemin if (snes->reason) PetscFunctionReturn(0); 329a312c225SMatthew G Knepley } 330a312c225SMatthew G Knepley snes->reason = SNES_DIVERGED_MAX_IT; 331a312c225SMatthew G Knepley PetscFunctionReturn(0); 332a312c225SMatthew G Knepley } 333a312c225SMatthew G Knepley 33423b3e82cSAsbjørn Nilsen Riseth /*@ 33523b3e82cSAsbjørn Nilsen Riseth SNESNGMRESSetRestartFmRise - Increase the restart count if the step x_M increases the residual F_M 33623b3e82cSAsbjørn Nilsen Riseth 33723b3e82cSAsbjørn Nilsen Riseth Input Parameters: 33823b3e82cSAsbjørn Nilsen Riseth + snes - the SNES context. 33923b3e82cSAsbjørn Nilsen Riseth - flg - boolean value deciding whether to use the option or not 34023b3e82cSAsbjørn Nilsen Riseth 34123b3e82cSAsbjørn Nilsen Riseth Options Database: 34223b3e82cSAsbjørn Nilsen Riseth + -snes_ngmres_restart_fm_rise - Increase the restart count if the step x_M increases the residual F_M 34323b3e82cSAsbjørn Nilsen Riseth 34423b3e82cSAsbjørn Nilsen Riseth Level: intermediate 34523b3e82cSAsbjørn Nilsen Riseth 34623b3e82cSAsbjørn Nilsen Riseth Notes: 34723b3e82cSAsbjø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. 34823b3e82cSAsbjørn Nilsen Riseth To help the solver do that, reset the Krylov subspace whenever F_M increases. 34923b3e82cSAsbjørn Nilsen Riseth 35023b3e82cSAsbjørn Nilsen Riseth This option must be used with SNES_NGMRES_RESTART_DIFFERENCE 35123b3e82cSAsbjørn Nilsen Riseth 35223b3e82cSAsbjørn Nilsen Riseth The default is FALSE. 35323b3e82cSAsbjørn Nilsen Riseth .seealso: SNES_NGMRES_RESTART_DIFFERENCE 35423b3e82cSAsbjørn Nilsen Riseth @*/ 35523b3e82cSAsbjørn Nilsen Riseth PetscErrorCode SNESNGMRESSetRestartFmRise(SNES snes,PetscBool flg) 35623b3e82cSAsbjørn Nilsen Riseth { 35723b3e82cSAsbjørn Nilsen Riseth PetscErrorCode (*f)(SNES,PetscBool); 35823b3e82cSAsbjørn Nilsen Riseth PetscErrorCode ierr; 35923b3e82cSAsbjørn Nilsen Riseth 36023b3e82cSAsbjørn Nilsen Riseth PetscFunctionBegin; 36123b3e82cSAsbjørn Nilsen Riseth ierr = PetscObjectQueryFunction((PetscObject)snes,"SNESNGMRESSetRestartFmRise_C",&f);CHKERRQ(ierr); 36223b3e82cSAsbjørn Nilsen Riseth if (f) {ierr = (f)(snes,flg);CHKERRQ(ierr);} 36323b3e82cSAsbjørn Nilsen Riseth PetscFunctionReturn(0); 36423b3e82cSAsbjørn Nilsen Riseth } 36523b3e82cSAsbjørn Nilsen Riseth 36623b3e82cSAsbjørn Nilsen Riseth PetscErrorCode SNESNGMRESSetRestartFmRise_NGMRES(SNES snes,PetscBool flg) 36723b3e82cSAsbjørn Nilsen Riseth { 36823b3e82cSAsbjørn Nilsen Riseth SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 36923b3e82cSAsbjørn Nilsen Riseth 37023b3e82cSAsbjørn Nilsen Riseth PetscFunctionBegin; 37123b3e82cSAsbjørn Nilsen Riseth ngmres->restart_fm_rise = flg; 37223b3e82cSAsbjørn Nilsen Riseth PetscFunctionReturn(0); 37323b3e82cSAsbjørn Nilsen Riseth } 37423b3e82cSAsbjørn Nilsen Riseth 37523b3e82cSAsbjørn Nilsen Riseth PetscErrorCode SNESNGMRESGetRestartFmRise(SNES snes,PetscBool *flg) 37623b3e82cSAsbjørn Nilsen Riseth { 37723b3e82cSAsbjørn Nilsen Riseth PetscErrorCode (*f)(SNES,PetscBool*); 37823b3e82cSAsbjørn Nilsen Riseth PetscErrorCode ierr; 37923b3e82cSAsbjørn Nilsen Riseth 38023b3e82cSAsbjørn Nilsen Riseth PetscFunctionBegin; 38123b3e82cSAsbjørn Nilsen Riseth ierr = PetscObjectQueryFunction((PetscObject)snes,"SNESNGMRESGetRestartFmRise_C",&f);CHKERRQ(ierr); 38223b3e82cSAsbjørn Nilsen Riseth if (f) {ierr = (f)(snes,flg);CHKERRQ(ierr);} 38323b3e82cSAsbjørn Nilsen Riseth PetscFunctionReturn(0); 38423b3e82cSAsbjørn Nilsen Riseth } 38523b3e82cSAsbjørn Nilsen Riseth 38623b3e82cSAsbjørn Nilsen Riseth PetscErrorCode SNESNGMRESGetRestartFmRise_NGMRES(SNES snes,PetscBool *flg) 38723b3e82cSAsbjørn Nilsen Riseth { 38823b3e82cSAsbjørn Nilsen Riseth SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 38923b3e82cSAsbjørn Nilsen Riseth 39023b3e82cSAsbjørn Nilsen Riseth PetscFunctionBegin; 39123b3e82cSAsbjørn Nilsen Riseth *flg = ngmres->restart_fm_rise; 39223b3e82cSAsbjørn Nilsen Riseth PetscFunctionReturn(0); 39323b3e82cSAsbjørn Nilsen Riseth } 39423b3e82cSAsbjørn Nilsen Riseth 39523b3e82cSAsbjørn Nilsen Riseth 39613a62661SPeter Brune /*@ 39713a62661SPeter Brune SNESNGMRESSetRestartType - Sets the restart type for SNESNGMRES. 39813a62661SPeter Brune 39913a62661SPeter Brune Logically Collective on SNES 40013a62661SPeter Brune 40113a62661SPeter Brune Input Parameters: 40213a62661SPeter Brune + snes - the iterative context 40313a62661SPeter Brune - rtype - restart type 40413a62661SPeter Brune 40513a62661SPeter Brune Options Database: 40613a62661SPeter Brune + -snes_ngmres_restart_type<difference,periodic,none> - set the restart type 4070c777b0cSPeter Brune - -snes_ngmres_restart[30] - sets the number of iterations before restart for periodic 40813a62661SPeter Brune 40913a62661SPeter Brune Level: intermediate 41013a62661SPeter Brune 41113a62661SPeter Brune SNESNGMRESRestartTypes: 41213a62661SPeter Brune + SNES_NGMRES_RESTART_NONE - never restart 41313a62661SPeter Brune . SNES_NGMRES_RESTART_DIFFERENCE - restart based upon difference criteria 41413a62661SPeter Brune - SNES_NGMRES_RESTART_PERIODIC - restart after a fixed number of iterations 41513a62661SPeter Brune 41613a62661SPeter Brune Notes: 41713a62661SPeter Brune The default line search used is the L2 line search and it requires two additional function evaluations. 41813a62661SPeter Brune 41913a62661SPeter Brune .keywords: SNES, SNESNGMRES, restart, type, set SNESLineSearch 42013a62661SPeter Brune @*/ 4210adebc6cSBarry Smith PetscErrorCode SNESNGMRESSetRestartType(SNES snes,SNESNGMRESRestartType rtype) 4220adebc6cSBarry Smith { 42313a62661SPeter Brune PetscErrorCode ierr; 4245fd66863SKarl Rupp 42513a62661SPeter Brune PetscFunctionBegin; 42613a62661SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42713a62661SPeter Brune ierr = PetscTryMethod(snes,"SNESNGMRESSetRestartType_C",(SNES,SNESNGMRESRestartType),(snes,rtype));CHKERRQ(ierr); 42813a62661SPeter Brune PetscFunctionReturn(0); 42913a62661SPeter Brune } 43013a62661SPeter Brune 43113a62661SPeter Brune /*@ 43213a62661SPeter Brune SNESNGMRESSetSelectType - Sets the selection type for SNESNGMRES. This determines how the candidate solution and 43313a62661SPeter Brune combined solution are used to create the next iterate. 43413a62661SPeter Brune 43513a62661SPeter Brune Logically Collective on SNES 43613a62661SPeter Brune 43713a62661SPeter Brune Input Parameters: 43813a62661SPeter Brune + snes - the iterative context 43913a62661SPeter Brune - stype - selection type 44013a62661SPeter Brune 44113a62661SPeter Brune Options Database: 44213a62661SPeter Brune . -snes_ngmres_select_type<difference,none,linesearch> 44313a62661SPeter Brune 44413a62661SPeter Brune Level: intermediate 44513a62661SPeter Brune 44613a62661SPeter Brune SNESNGMRESSelectTypes: 44713a62661SPeter Brune + SNES_NGMRES_SELECT_NONE - choose the combined solution all the time 44813a62661SPeter Brune . SNES_NGMRES_SELECT_DIFFERENCE - choose based upon the selection criteria 44913a62661SPeter Brune - SNES_NGMRES_SELECT_LINESEARCH - choose based upon line search combination 45013a62661SPeter Brune 45113a62661SPeter Brune Notes: 45213a62661SPeter Brune The default line search used is the L2 line search and it requires two additional function evaluations. 45313a62661SPeter Brune 45413a62661SPeter Brune .keywords: SNES, SNESNGMRES, selection, type, set SNESLineSearch 45513a62661SPeter Brune @*/ 4560adebc6cSBarry Smith PetscErrorCode SNESNGMRESSetSelectType(SNES snes,SNESNGMRESSelectType stype) 4570adebc6cSBarry Smith { 45813a62661SPeter Brune PetscErrorCode ierr; 4595fd66863SKarl Rupp 46013a62661SPeter Brune PetscFunctionBegin; 46113a62661SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 46213a62661SPeter Brune ierr = PetscTryMethod(snes,"SNESNGMRESSetSelectType_C",(SNES,SNESNGMRESSelectType),(snes,stype));CHKERRQ(ierr); 46313a62661SPeter Brune PetscFunctionReturn(0); 46413a62661SPeter Brune } 46513a62661SPeter Brune 4660adebc6cSBarry Smith PetscErrorCode SNESNGMRESSetSelectType_NGMRES(SNES snes,SNESNGMRESSelectType stype) 4670adebc6cSBarry Smith { 46813a62661SPeter Brune SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 4695fd66863SKarl Rupp 47013a62661SPeter Brune PetscFunctionBegin; 47113a62661SPeter Brune ngmres->select_type = stype; 47213a62661SPeter Brune PetscFunctionReturn(0); 47313a62661SPeter Brune } 47413a62661SPeter Brune 4750adebc6cSBarry Smith PetscErrorCode SNESNGMRESSetRestartType_NGMRES(SNES snes,SNESNGMRESRestartType rtype) 4760adebc6cSBarry Smith { 47713a62661SPeter Brune SNES_NGMRES *ngmres = (SNES_NGMRES*)snes->data; 4785fd66863SKarl Rupp 47913a62661SPeter Brune PetscFunctionBegin; 48013a62661SPeter Brune ngmres->restart_type = rtype; 48113a62661SPeter Brune PetscFunctionReturn(0); 48213a62661SPeter Brune } 48313a62661SPeter Brune 484dfbf837cSBarry Smith /*MC 4851867fe5bSPeter Brune SNESNGMRES - The Nonlinear Generalized Minimum Residual method. 486a312c225SMatthew G Knepley 487dfbf837cSBarry Smith Level: beginner 488dfbf837cSBarry Smith 4891867fe5bSPeter Brune Options Database: 49013a62661SPeter Brune + -snes_ngmres_select_type<difference,none,linesearch> - choose the select between candidate and combined solution 49138774f0aSPeter Brune . -snes_ngmres_restart_type<difference,none,periodic> - choose the restart conditions 49238774f0aSPeter Brune . -snes_ngmres_candidate - Use NGMRES variant which combines candidate solutions instead of actual solutions 49313a62661SPeter Brune . -snes_ngmres_m - Number of stored previous solutions and residuals 49413a62661SPeter Brune . -snes_ngmres_restart_it - Number of iterations the restart conditions hold before restart 49513a62661SPeter Brune . -snes_ngmres_gammaA - Residual tolerance for solution select between the candidate and combination 49613a62661SPeter Brune . -snes_ngmres_gammaC - Residual tolerance for restart 49713a62661SPeter Brune . -snes_ngmres_epsilonB - Difference tolerance between subsequent solutions triggering restart 49813a62661SPeter Brune . -snes_ngmres_deltaB - Difference tolerance between residuals triggering restart 49923b3e82cSAsbjørn Nilsen Riseth . -snes_ngmres_restart_fm_rise - Restart on residual rise from x_M step 50013a62661SPeter Brune . -snes_ngmres_monitor - Prints relevant information about the ngmres iteration 5015c3e6ab7SPeter Brune . -snes_linesearch_type <basic,l2,cp> - Line search type used for the default smoother 50213a62661SPeter Brune - -additive_snes_linesearch_type - linesearch type used to select between the candidate and combined solution with additive select type 5031867fe5bSPeter Brune 5041867fe5bSPeter Brune Notes: 5051867fe5bSPeter Brune 5061867fe5bSPeter Brune The N-GMRES method combines m previous solutions into a minimum-residual solution by solving a small linearized 5071867fe5bSPeter Brune optimization problem at each iteration. 5081867fe5bSPeter Brune 5094f02bc6aSBarry Smith Very similar to the SNESANDERSON algorithm. 5104f02bc6aSBarry Smith 5111867fe5bSPeter Brune References: 51296a0c994SBarry Smith + 1. - C. W. Oosterlee and T. Washio, "Krylov Subspace Acceleration of Nonlinear Multigrid with Application to Recirculating Flows", 513dfbf837cSBarry Smith SIAM Journal on Scientific Computing, 21(5), 2000. 51496a0c994SBarry Smith - 2. - Peter R. Brune, Matthew G. Knepley, Barry F. Smith, and Xuemin Tu, "Composing Scalable Nonlinear Algebraic Solvers", 5154f02bc6aSBarry Smith SIAM Review, 57(4), 2015 5164f02bc6aSBarry Smith 5174f02bc6aSBarry Smith 518dfbf837cSBarry Smith .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types) 519dfbf837cSBarry Smith M*/ 520a312c225SMatthew G Knepley 5218cc058d9SJed Brown PETSC_EXTERN PetscErrorCode SNESCreate_NGMRES(SNES snes) 522a312c225SMatthew G Knepley { 523a312c225SMatthew G Knepley SNES_NGMRES *ngmres; 524a312c225SMatthew G Knepley PetscErrorCode ierr; 525*d8d34be6SBarry Smith SNESLineSearch linesearch; 526a312c225SMatthew G Knepley 527a312c225SMatthew G Knepley PetscFunctionBegin; 528a312c225SMatthew G Knepley snes->ops->destroy = SNESDestroy_NGMRES; 529a312c225SMatthew G Knepley snes->ops->setup = SNESSetUp_NGMRES; 530a312c225SMatthew G Knepley snes->ops->setfromoptions = SNESSetFromOptions_NGMRES; 531a312c225SMatthew G Knepley snes->ops->view = SNESView_NGMRES; 532a312c225SMatthew G Knepley snes->ops->solve = SNESSolve_NGMRES; 533a312c225SMatthew G Knepley snes->ops->reset = SNESReset_NGMRES; 534a312c225SMatthew G Knepley 535efd4aadfSBarry Smith snes->usesnpc = PETSC_TRUE; 5362c155ee1SBarry Smith snes->usesksp = PETSC_FALSE; 537efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 5382c155ee1SBarry Smith 5394fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_TRUE; 5404fc747eaSLawrence Mitchell 541b00a9115SJed Brown ierr = PetscNewLog(snes,&ngmres);CHKERRQ(ierr); 542a312c225SMatthew G Knepley snes->data = (void*) ngmres; 543d2e16ddcSPeter Brune ngmres->msize = 30; 54419653cdaSPeter Brune 54588976e71SPeter Brune if (!snes->tolerancesset) { 5460e444f03SPeter Brune snes->max_funcs = 30000; 5470e444f03SPeter Brune snes->max_its = 10000; 54888976e71SPeter Brune } 5490e444f03SPeter Brune 55038774f0aSPeter Brune ngmres->candidate = PETSC_FALSE; 551d2e16ddcSPeter Brune 552*d8d34be6SBarry Smith ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 553*d8d34be6SBarry Smith ierr = SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);CHKERRQ(ierr); 554*d8d34be6SBarry Smith 5550298fd71SBarry Smith ngmres->additive_linesearch = NULL; 556077c4231SPeter Brune ngmres->approxfunc = PETSC_FALSE; 55728ed4a04SPeter Brune ngmres->restart_it = 2; 55813a62661SPeter Brune ngmres->restart_periodic = 30; 559f109b39eSPeter Brune ngmres->gammaA = 2.0; 560f109b39eSPeter Brune ngmres->gammaC = 2.0; 561cac108bcSPeter Brune ngmres->deltaB = 0.9; 562cac108bcSPeter Brune ngmres->epsilonB = 0.1; 56323b3e82cSAsbjørn Nilsen Riseth ngmres->restart_fm_rise = PETSC_FALSE; 564e7058c64SPeter Brune 56513a62661SPeter Brune ngmres->restart_type = SNES_NGMRES_RESTART_DIFFERENCE; 56613a62661SPeter Brune ngmres->select_type = SNES_NGMRES_SELECT_DIFFERENCE; 56713a62661SPeter Brune 568bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESNGMRESSetSelectType_C",SNESNGMRESSetSelectType_NGMRES);CHKERRQ(ierr); 569bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESNGMRESSetRestartType_C",SNESNGMRESSetRestartType_NGMRES);CHKERRQ(ierr); 57023b3e82cSAsbjørn Nilsen Riseth ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESNGMRESSetRestartFmRise_C",SNESNGMRESSetRestartFmRise_NGMRES);CHKERRQ(ierr); 57123b3e82cSAsbjørn Nilsen Riseth ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESNGMRESGetRestartFmRise_C",SNESNGMRESGetRestartFmRise_NGMRES);CHKERRQ(ierr); 572a312c225SMatthew G Knepley PetscFunctionReturn(0); 573a312c225SMatthew G Knepley } 574