void Solve_Distance(UserCtx *user, int iter) { SNES snes_distance; KSP ksp; PC pc; Vec r; Mat J; double norm; int bi=0; VecDuplicate(LevelSet, &r); SNESCreate(PETSC_COMM_WORLD,&snes_distance); SNESSetFunction(snes_distance,r,FormFunction_Distance,(void *)&user[bi]); MatCreateSNESMF(snes_distance, &J); SNESSetJacobian(snes_distance,J,J,MatMFFDComputeJacobian,(void *)&user[bi]); SNESSetType(snes_distance, SNESTR); //SNESTR,SNESLS double tol=1.e-2; SNESSetMaxLinearSolveFailures(snes_distance,10000); SNESSetMaxNonlinearStepFailures(snes_distance,10000); SNESKSPSetUseEW(snes_distance, PETSC_TRUE); SNESKSPSetParametersEW(snes_distance,3,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); SNESSetTolerances(snes_distance,PETSC_DEFAULT,tol,PETSC_DEFAULT,5,50000); // snes iter SNESGetKSP(snes_distance, &ksp); KSPSetType(ksp, KSPGMRES); //KSPGMRESSetPreAllocateVectors(ksp); KSPGetPC(ksp,&pc); PCSetType(pc,PCNONE); //int maxits=10; int maxits=4; // ksp iter double rtol=tol, atol=PETSC_DEFAULT, dtol=PETSC_DEFAULT; KSPSetTolerances(ksp,rtol,atol,dtol,maxits); extern PetscErrorCode MySNESMonitor(SNES snes,PetscInt n,PetscReal rnorm,void *dummy); SNESMonitorSet(snes_distance,MySNESMonitor,PETSC_NULL,PETSC_NULL); SNESSolve(snes_distance, PETSC_NULL, LevelSet); SNESGetFunctionNorm(snes_distance, &norm); //PetscPrintf(PETSC_COMM_WORLD, "\nDistance SNES residual norm=%.5e\n\n", norm); VecDestroy(r); MatDestroy(J); SNESDestroy(snes_distance); };
void petscSetDefaults(FEProblem & problem) { // dig out Petsc solver NonlinearSystem & nl = problem.getNonlinearSystem(); PetscNonlinearSolver<Number> * petsc_solver = dynamic_cast<PetscNonlinearSolver<Number> *>(nl.sys().nonlinear_solver.get()); SNES snes = petsc_solver->snes(); KSP ksp; SNESGetKSP(snes, &ksp); PCSide pcside = getPetscPCSide(nl.getPCSide()); #if PETSC_VERSION_LESS_THAN(3,2,0) // PETSc 3.1.x- KSPSetPreconditionerSide(ksp, pcside); #else // PETSc 3.2.x+ KSPSetPCSide(ksp, pcside); #endif SNESSetMaxLinearSolveFailures(snes, 1000000); #if PETSC_VERSION_LESS_THAN(3,0,0) // PETSc 2.3.3- KSPSetConvergenceTest(ksp, petscConverged, &problem); SNESSetConvergenceTest(snes, petscNonlinearConverged, &problem); #else // PETSc 3.0.0+ // In 3.0.0, the context pointer must actually be used, and the // final argument to KSPSetConvergenceTest() is a pointer to a // routine for destroying said private data context. In this case, // we use the default context provided by PETSc in addition to // a few other tests. { PetscErrorCode ierr = KSPSetConvergenceTest(ksp, petscConverged, &problem, PETSC_NULL); CHKERRABORT(nl.comm().get(),ierr); ierr = SNESSetConvergenceTest(snes, petscNonlinearConverged, &problem, PETSC_NULL); CHKERRABORT(nl.comm().get(),ierr); } #endif }