/* Creates the default smoother type. This is SNESNRICHARDSON on each fine level and SNESNEWTONLS on the coarse level. */ PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES snes, SNES *smooth) { SNES_FAS *fas; const char *optionsprefix; char tprefix[128]; PetscErrorCode ierr; SNES nsmooth; PetscFunctionBegin; PetscValidHeaderSpecific(snes,SNES_CLASSID,1); fas = (SNES_FAS*)snes->data; ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr); /* create the default smoother */ ierr = SNESCreate(PetscObjectComm((PetscObject)snes), &nsmooth);CHKERRQ(ierr); if (fas->level == 0) { sprintf(tprefix,"fas_coarse_"); ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr); ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr); ierr = SNESSetType(nsmooth, SNESNEWTONLS);CHKERRQ(ierr); ierr = SNESSetTolerances(nsmooth, nsmooth->abstol, nsmooth->rtol, nsmooth->stol, nsmooth->max_its, nsmooth->max_funcs);CHKERRQ(ierr); } else { sprintf(tprefix,"fas_levels_%d_",(int)fas->level); ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr); ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr); ierr = SNESSetType(nsmooth, SNESNRICHARDSON);CHKERRQ(ierr); ierr = SNESSetTolerances(nsmooth, 0.0, 0.0, 0.0, fas->max_down_it, nsmooth->max_funcs);CHKERRQ(ierr); } ierr = PetscObjectIncrementTabLevel((PetscObject)nsmooth, (PetscObject)snes, 1);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)nsmooth);CHKERRQ(ierr); ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)nsmooth);CHKERRQ(ierr); *smooth = nsmooth; PetscFunctionReturn(0); }
static PetscErrorCode SNESCompositeAddSNES_Composite(SNES snes,SNESType type) { SNES_Composite *jac; SNES_CompositeLink next,ilink; PetscErrorCode ierr; PetscInt cnt = 0; const char *prefix; char newprefix[20]; DM dm; PetscFunctionBegin; ierr = PetscNewLog(snes,&ilink);CHKERRQ(ierr); ilink->next = 0; ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&ilink->snes);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)ilink->snes);CHKERRQ(ierr); ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); ierr = SNESSetDM(ilink->snes,dm);CHKERRQ(ierr); ierr = SNESSetTolerances(ilink->snes,ilink->snes->abstol,ilink->snes->rtol,ilink->snes->stol,1,ilink->snes->max_funcs);CHKERRQ(ierr); ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)ilink->snes);CHKERRQ(ierr); jac = (SNES_Composite*)snes->data; next = jac->head; if (!next) { jac->head = ilink; ilink->previous = NULL; } else { cnt++; while (next->next) { next = next->next; cnt++; } next->next = ilink; ilink->previous = next; } ierr = SNESGetOptionsPrefix(snes,&prefix);CHKERRQ(ierr); ierr = SNESSetOptionsPrefix(ilink->snes,prefix);CHKERRQ(ierr); sprintf(newprefix,"sub_%d_",(int)cnt); ierr = SNESAppendOptionsPrefix(ilink->snes,newprefix);CHKERRQ(ierr); ierr = PetscObjectIncrementTabLevel((PetscObject)ilink->snes,(PetscObject)snes,1);CHKERRQ(ierr); ierr = SNESSetType(ilink->snes,type);CHKERRQ(ierr); ierr = SNESSetNormSchedule(ilink->snes, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); ilink->dmp = 1.0; jac->nsnes++; PetscFunctionReturn(0); }
PetscErrorCode SNESSetUp_FAS(SNES snes) { SNES_FAS *fas = (SNES_FAS*) snes->data; PetscErrorCode ierr; PetscInt dm_levels; Vec vec_sol, vec_func, vec_sol_update, vec_rhs; /* preserve these if they're set through the reset */ SNES next; PetscBool isFine; SNESLineSearch linesearch; SNESLineSearch slinesearch; void *lsprectx,*lspostctx; PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); PetscFunctionBegin; ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr); if (fas->usedmfornumberoflevels && isFine) { ierr = DMGetRefineLevel(snes->dm,&dm_levels);CHKERRQ(ierr); dm_levels++; if (dm_levels > fas->levels) { /* we don't want the solution and func vectors to be destroyed in the SNESReset when it's called in SNESFASSetLevels_FAS*/ vec_sol = snes->vec_sol; vec_func = snes->vec_func; vec_sol_update = snes->vec_sol_update; vec_rhs = snes->vec_rhs; snes->vec_sol = NULL; snes->vec_func = NULL; snes->vec_sol_update = NULL; snes->vec_rhs = NULL; /* reset the number of levels */ ierr = SNESFASSetLevels(snes,dm_levels,NULL);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); snes->vec_sol = vec_sol; snes->vec_func = vec_func; snes->vec_rhs = vec_rhs; snes->vec_sol_update = vec_sol_update; } } ierr = SNESFASCycleGetCorrection(snes, &next);CHKERRQ(ierr); if (!isFine) snes->gridsequence = 0; /* no grid sequencing inside the multigrid hierarchy! */ ierr = SNESSetWorkVecs(snes, 2);CHKERRQ(ierr); /* work vectors used for intergrid transfers */ /* set up the smoothers if they haven't already been set up */ if (!fas->smoothd) { ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);CHKERRQ(ierr); } if (snes->dm) { /* set the smoother DMs properly */ if (fas->smoothu) ierr = SNESSetDM(fas->smoothu, snes->dm);CHKERRQ(ierr); ierr = SNESSetDM(fas->smoothd, snes->dm);CHKERRQ(ierr); /* construct EVERYTHING from the DM -- including the progressive set of smoothers */ if (next) { /* for now -- assume the DM and the evaluation functions have been set externally */ if (!next->dm) { ierr = DMCoarsen(snes->dm, PetscObjectComm((PetscObject)next), &next->dm);CHKERRQ(ierr); ierr = SNESSetDM(next, next->dm);CHKERRQ(ierr); } /* set the interpolation and restriction from the DM */ if (!fas->interpolate) { ierr = DMCreateInterpolation(next->dm, snes->dm, &fas->interpolate, &fas->rscale);CHKERRQ(ierr); if (!fas->restrct) { ierr = PetscObjectReference((PetscObject)fas->interpolate);CHKERRQ(ierr); fas->restrct = fas->interpolate; } } /* set the injection from the DM */ if (!fas->inject) { ierr = DMCreateInjection(next->dm, snes->dm, &fas->inject);CHKERRQ(ierr); } } } /*pass the smoother, function, and jacobian up to the next level if it's not user set already */ if (fas->galerkin) { if (next) { ierr = SNESSetFunction(next, NULL, SNESFASGalerkinDefaultFunction, next);CHKERRQ(ierr); } if (fas->smoothd && fas->level != fas->levels - 1) { ierr = SNESSetFunction(fas->smoothd, NULL, SNESFASGalerkinDefaultFunction, snes);CHKERRQ(ierr); } if (fas->smoothu && fas->level != fas->levels - 1) { ierr = SNESSetFunction(fas->smoothu, NULL, SNESFASGalerkinDefaultFunction, snes);CHKERRQ(ierr); } } /* sets the down (pre) smoother's default norm and sets it from options */ if (fas->smoothd) { if (fas->level == 0 && fas->levels != 1) { ierr = SNESSetNormSchedule(fas->smoothd, SNES_NORM_NONE);CHKERRQ(ierr); } else { ierr = SNESSetNormSchedule(fas->smoothd, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); } ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)fas->smoothd);CHKERRQ(ierr); ierr = SNESSetFromOptions(fas->smoothd);CHKERRQ(ierr); ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); ierr = SNESGetLineSearch(fas->smoothd,&slinesearch);CHKERRQ(ierr); ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); ierr = SNESLineSearchSetPreCheck(slinesearch,precheck,lsprectx);CHKERRQ(ierr); ierr = SNESLineSearchSetPostCheck(slinesearch,postcheck,lspostctx);CHKERRQ(ierr); ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)slinesearch);CHKERRQ(ierr); fas->smoothd->vec_sol = snes->vec_sol; ierr = PetscObjectReference((PetscObject)snes->vec_sol);CHKERRQ(ierr); fas->smoothd->vec_sol_update = snes->vec_sol_update; ierr = PetscObjectReference((PetscObject)snes->vec_sol_update);CHKERRQ(ierr); fas->smoothd->vec_func = snes->vec_func; ierr = PetscObjectReference((PetscObject)snes->vec_func);CHKERRQ(ierr); if (fas->eventsmoothsetup) {ierr = PetscLogEventBegin(fas->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} ierr = SNESSetUp(fas->smoothd);CHKERRQ(ierr); if (fas->eventsmoothsetup) {ierr = PetscLogEventEnd(fas->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} } /* sets the up (post) smoother's default norm and sets it from options */ if (fas->smoothu) { if (fas->level != fas->levels - 1) { ierr = SNESSetNormSchedule(fas->smoothu, SNES_NORM_NONE);CHKERRQ(ierr); } else { ierr = SNESSetNormSchedule(fas->smoothu, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); } ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)fas->smoothu);CHKERRQ(ierr); ierr = SNESSetFromOptions(fas->smoothu);CHKERRQ(ierr); ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); ierr = SNESGetLineSearch(fas->smoothu,&slinesearch);CHKERRQ(ierr); ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); ierr = SNESLineSearchSetPreCheck(slinesearch,precheck,lsprectx);CHKERRQ(ierr); ierr = SNESLineSearchSetPostCheck(slinesearch,postcheck,lspostctx);CHKERRQ(ierr); ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)slinesearch);CHKERRQ(ierr); fas->smoothu->vec_sol = snes->vec_sol; ierr = PetscObjectReference((PetscObject)snes->vec_sol);CHKERRQ(ierr); fas->smoothu->vec_sol_update = snes->vec_sol_update; ierr = PetscObjectReference((PetscObject)snes->vec_sol_update);CHKERRQ(ierr); fas->smoothu->vec_func = snes->vec_func; ierr = PetscObjectReference((PetscObject)snes->vec_func);CHKERRQ(ierr); if (fas->eventsmoothsetup) {ierr = PetscLogEventBegin(fas->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} ierr = SNESSetUp(fas->smoothu);CHKERRQ(ierr); if (fas->eventsmoothsetup) {ierr = PetscLogEventEnd(fas->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} } if (next) { /* gotta set up the solution vector for this to work */ if (!next->vec_sol) {ierr = SNESFASCreateCoarseVec(snes,&next->vec_sol);CHKERRQ(ierr);} if (!next->vec_rhs) {ierr = SNESFASCreateCoarseVec(snes,&next->vec_rhs);CHKERRQ(ierr);} ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)next);CHKERRQ(ierr); ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); ierr = SNESGetLineSearch(fas->next,&slinesearch);CHKERRQ(ierr); ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); ierr = SNESLineSearchSetPreCheck(slinesearch,precheck,lsprectx);CHKERRQ(ierr); ierr = SNESLineSearchSetPostCheck(slinesearch,postcheck,lspostctx);CHKERRQ(ierr); ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)slinesearch);CHKERRQ(ierr); ierr = SNESSetUp(next);CHKERRQ(ierr); } /* setup FAS work vectors */ if (fas->galerkin) { ierr = VecDuplicate(snes->vec_sol, &fas->Xg);CHKERRQ(ierr); ierr = VecDuplicate(snes->vec_sol, &fas->Fg);CHKERRQ(ierr); } PetscFunctionReturn(0); }