static PetscErrorCode KSPSetupMonitor_Private(KSP ksp, PetscViewer viewer, PetscViewerFormat format, PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,void*), PetscBool useMonitor) { PetscErrorCode ierr; PetscFunctionBegin; if (useMonitor) { PetscViewerAndFormat *vf; ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp, monitor, vf, (PetscErrorCode (*)(void**)) PetscViewerAndFormatDestroy);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode SNESSetFromOptions_FAS(PetscOptionItems *PetscOptionsObject,SNES snes) { SNES_FAS *fas = (SNES_FAS*) snes->data; PetscInt levels = 1; PetscBool flg = PETSC_FALSE, upflg = PETSC_FALSE, downflg = PETSC_FALSE, monflg = PETSC_FALSE, galerkinflg = PETSC_FALSE,continuationflg = PETSC_FALSE; PetscErrorCode ierr; SNESFASType fastype; const char *optionsprefix; SNESLineSearch linesearch; PetscInt m, n_up, n_down; SNES next; PetscBool isFine; PetscFunctionBegin; ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr); ierr = PetscOptionsHead(PetscOptionsObject,"SNESFAS Options-----------------------------------");CHKERRQ(ierr); /* number of levels -- only process most options on the finest level */ if (isFine) { ierr = PetscOptionsInt("-snes_fas_levels", "Number of Levels", "SNESFASSetLevels", levels, &levels, &flg);CHKERRQ(ierr); if (!flg && snes->dm) { ierr = DMGetRefineLevel(snes->dm,&levels);CHKERRQ(ierr); levels++; fas->usedmfornumberoflevels = PETSC_TRUE; } ierr = SNESFASSetLevels(snes, levels, NULL);CHKERRQ(ierr); fastype = fas->fastype; ierr = PetscOptionsEnum("-snes_fas_type","FAS correction type","SNESFASSetType",SNESFASTypes,(PetscEnum)fastype,(PetscEnum*)&fastype,&flg);CHKERRQ(ierr); if (flg) { ierr = SNESFASSetType(snes, fastype);CHKERRQ(ierr); } ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); ierr = PetscOptionsInt("-snes_fas_cycles","Number of cycles","SNESFASSetCycles",fas->n_cycles,&m,&flg);CHKERRQ(ierr); if (flg) { ierr = SNESFASSetCycles(snes, m);CHKERRQ(ierr); } ierr = PetscOptionsBool("-snes_fas_continuation","Corrected grid-sequence continuation","SNESFASSetContinuation",fas->continuation,&continuationflg,&flg);CHKERRQ(ierr); if (flg) { ierr = SNESFASSetContinuation(snes,continuationflg);CHKERRQ(ierr); } ierr = PetscOptionsBool("-snes_fas_galerkin", "Form coarse problems with Galerkin","SNESFASSetGalerkin",fas->galerkin,&galerkinflg,&flg);CHKERRQ(ierr); if (flg) { ierr = SNESFASSetGalerkin(snes, galerkinflg);CHKERRQ(ierr); } if (fas->fastype == SNES_FAS_FULL) { ierr = PetscOptionsBool("-snes_fas_full_downsweep","Smooth on the initial upsweep for full FAS cycles","SNESFASFullSetDownSweep",fas->full_downsweep,&fas->full_downsweep,&flg);CHKERRQ(ierr); if (flg) {SNESFASFullSetDownSweep(snes,fas->full_downsweep);CHKERRQ(ierr);} } ierr = PetscOptionsInt("-snes_fas_smoothup","Number of post-smoothing steps","SNESFASSetNumberSmoothUp",fas->max_up_it,&n_up,&upflg);CHKERRQ(ierr); ierr = PetscOptionsInt("-snes_fas_smoothdown","Number of pre-smoothing steps","SNESFASSetNumberSmoothDown",fas->max_down_it,&n_down,&downflg);CHKERRQ(ierr); { PetscViewer viewer; PetscViewerFormat format; ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix, "-snes_fas_monitor",&viewer,&format,&monflg);CHKERRQ(ierr); if (monflg) { PetscViewerAndFormat *vf; ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); ierr = SNESFASSetMonitor(snes,vf,PETSC_TRUE);CHKERRQ(ierr); } } flg = PETSC_FALSE; monflg = PETSC_TRUE; ierr = PetscOptionsBool("-snes_fas_log","Log times for each FAS level","SNESFASSetLog",monflg,&monflg,&flg);CHKERRQ(ierr); if (flg) {ierr = SNESFASSetLog(snes,monflg);CHKERRQ(ierr);} } ierr = PetscOptionsTail();CHKERRQ(ierr); /* setup from the determined types if there is no pointwise procedure or smoother defined */ if (upflg) { ierr = SNESFASSetNumberSmoothUp(snes,n_up);CHKERRQ(ierr); } if (downflg) { ierr = SNESFASSetNumberSmoothDown(snes,n_down);CHKERRQ(ierr); } /* set up the default line search for coarse grid corrections */ if (fas->fastype == SNES_FAS_ADDITIVE) { if (!snes->linesearch) { ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHL2);CHKERRQ(ierr); } } ierr = SNESFASCycleGetCorrection(snes, &next);CHKERRQ(ierr); /* recursive option setting for the smoothers */ if (next) {ierr = SNESSetFromOptions(next);CHKERRQ(ierr);} PetscFunctionReturn(0); }
PETSC_EXTERN void PETSC_STDCALL petscviewerandformatcreate_(PetscViewer *vin, PetscViewerFormat *format, PetscViewerAndFormat **vf, PetscErrorCode *ierr) { PetscViewer v; PetscPatchDefaultViewers_Fortran(vin, v); *ierr = PetscViewerAndFormatCreate(v, *format, vf); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec x,r; /* solution, residual vectors */ PetscInt steps,maxsteps = 100; /* iterations for convergence */ PetscErrorCode ierr; DM da; PetscReal ftime; SNES ts_snes; PetscViewerAndFormat *vf; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-8,-8,PETSC_DECIDE,PETSC_DECIDE, 2,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"v");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,FormFunction,da);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,1.0);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyTSMonitor,0,0);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSGetSNES(ts,&ts_snes); ierr = PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_DEFAULT,&vf);CHKERRQ(ierr); ierr = SNESMonitorSet(ts_snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void *))MySNESMonitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(da,x);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.0001);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }