void PetscDiffSolver::init () { START_LOG("init()", "PetscDiffSolver"); Parent::init(); int ierr=0; #if PETSC_VERSION_LESS_THAN(2,1,2) // At least until Petsc 2.1.1, the SNESCreate had a different // calling syntax. The second argument was of type SNESProblemType, // and could have a value of either SNES_NONLINEAR_EQUATIONS or // SNES_UNCONSTRAINED_MINIMIZATION. ierr = SNESCreate(libMesh::COMM_WORLD, SNES_NONLINEAR_EQUATIONS, &_snes); CHKERRABORT(libMesh::COMM_WORLD,ierr); #else ierr = SNESCreate(libMesh::COMM_WORLD,&_snes); CHKERRABORT(libMesh::COMM_WORLD,ierr); #endif #if PETSC_VERSION_LESS_THAN(2,3,3) ierr = SNESSetMonitor (_snes, __libmesh_petsc_diff_solver_monitor, this, PETSC_NULL); #else // API name change in PETSc 2.3.3 ierr = SNESMonitorSet (_snes, __libmesh_petsc_diff_solver_monitor, this, PETSC_NULL); #endif CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = SNESSetFromOptions(_snes); CHKERRABORT(libMesh::COMM_WORLD,ierr); STOP_LOG("init()", "PetscDiffSolver"); }
/*@ SNESFASSetMonitor - Sets the method-specific cycle monitoring Logically Collective on SNES Input Parameters: + snes - the FAS context - flg - monitor or not Level: advanced .keywords: FAS, monitor .seealso: SNESFASSetCyclesOnLevel() @*/ PetscErrorCode SNESFASSetMonitor(SNES snes, PetscBool flg) { SNES_FAS *fas = (SNES_FAS*)snes->data; PetscErrorCode ierr; PetscBool isFine; PetscInt i, levels = fas->levels; SNES levelsnes; PetscFunctionBegin; ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr); if (isFine) { for (i = 0; i < levels; i++) { ierr = SNESFASGetCycleSNES(snes, i, &levelsnes);CHKERRQ(ierr); fas = (SNES_FAS*)levelsnes->data; if (flg) { fas->monitor = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)levelsnes));CHKERRQ(ierr); /* set the monitors for the upsmoother and downsmoother */ ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr); ierr = SNESMonitorSet(levelsnes,SNESMonitorDefault,NULL,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } else if (i != fas->levels - 1) { /* unset the monitors on the coarse levels */ ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr); } } } PetscFunctionReturn(0); }
void PetscOutputter::timestepSetupInternal() { // Only execute if PETSc exists #ifdef LIBMESH_HAVE_PETSC // Extract the non-linear and linear solvers from PETSc NonlinearSystem & nl = _problem_ptr->getNonlinearSystem(); PetscNonlinearSolver<Number> * petsc_solver = dynamic_cast<PetscNonlinearSolver<Number> *>(nl.sys().nonlinear_solver.get()); SNES snes = petsc_solver->snes(); KSP ksp; SNESGetKSP(snes, &ksp); // Update the pseudo times _nonlinear_time = _time_old; // non-linear time starts with the previous time step _nonlinear_dt = _dt/_nonlinear_dt_divisor; // set the pseudo non-linear timestep _linear_dt = _nonlinear_dt/_linear_dt_divisor; // set the pseudo linear timestep // Set the PETSc monitor functions if (_output_nonlinear || (_time >= _nonlinear_start_time - _t_tol && _time <= _nonlinear_end_time + _t_tol) ) { PetscErrorCode ierr = SNESMonitorSet(snes, petscNonlinearOutput, this, PETSC_NULL); CHKERRABORT(libMesh::COMM_WORLD,ierr); } if (_output_linear || (_time >= _linear_start_time - _t_tol && _time <= _linear_end_time + _t_tol) ) { PetscErrorCode ierr = KSPMonitorSet(ksp, petscLinearOutput, this, PETSC_NULL); CHKERRABORT(libMesh::COMM_WORLD,ierr); } #endif }
int main(int argc,char **argv) { PetscErrorCode ierr; UserCtx user; DM red,da; SNES snes; DM packer; PetscBool use_monitor = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr; ierr = PetscOptionsSetFromOptions(NULL);CHKERRQ(ierr); /* Hardwire several options; can be changed at command line */ ierr = PetscOptionsInsertString(NULL,common_options);CHKERRQ(ierr); ierr = PetscOptionsInsertString(NULL,matrix_free_options);CHKERRQ(ierr); ierr = PetscOptionsInsert(NULL,&argc,&argv,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-use_monitor",&use_monitor,PETSC_IGNORE);CHKERRQ(ierr); /* Create a global vector that includes a single redundant array and two da arrays */ ierr = DMCompositeCreate(PETSC_COMM_WORLD,&packer);CHKERRQ(ierr); ierr = DMRedundantCreate(PETSC_COMM_WORLD,0,1,&red);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(red,"red_");CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,red);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-5,2,1,NULL,&da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(red,"da_");CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,(DM)da);CHKERRQ(ierr); ierr = DMSetApplicationContext(packer,&user);CHKERRQ(ierr); packer->ops->creatematrix = DMCreateMatrix_MF; /* create nonlinear multi-level solver */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,packer);CHKERRQ(ierr); ierr = SNESSetFunction(snes,NULL,ComputeFunction,NULL);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,NULL, NULL,ComputeJacobian_MF,NULL);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); if (use_monitor) { /* create graphics windows */ ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"u_lambda - state variables and Lagrange multipliers",-1,-1,-1,-1,&user.u_lambda_viewer);CHKERRQ(ierr); ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"fu_lambda - derivate w.r.t. state variables and Lagrange multipliers",-1,-1,-1,-1,&user.fu_lambda_viewer);CHKERRQ(ierr); ierr = SNESMonitorSet(snes,Monitor,0,0);CHKERRQ(ierr); } ierr = SNESSolve(snes,NULL,NULL);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&red);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = DMDestroy(&packer);CHKERRQ(ierr); if (use_monitor) { ierr = PetscViewerDestroy(&user.u_lambda_viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&user.fu_lambda_viewer);CHKERRQ(ierr); } ierr = PetscFinalize(); return ierr; }
/** In theory we have SolveTimeDependent and SolveSteadyState, the latter doesn't work very well. @param ctx the application context */ PetscErrorCode SolveTimeDependent(void* ctx) { User user = (User)ctx; PetscMPIInt rank, size; PetscErrorCode ierr; Algebra algebra = user->algebra; PetscLogDouble v1, v2; SNESConvergedReason snesreason; PetscFunctionBegin; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); /* set current time and step */ user->current_time = user->initial_time; user->current_step = 1; ierr = SNESMonitorSet(user->snes, MonitorFunction, (void*) user, PETSC_NULL);CHKERRQ(ierr); /* start the time step iteration */ while (user->current_time < (user->final_time - 0.05 * user->dt)) { /*Do a simple adaptive time step size*/ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); ierr = VecCopy(algebra->fn, algebra->oldfn);CHKERRQ(ierr); /* b) update the current time */ user->current_time += user->dt; ierr = PetscPrintf(PETSC_COMM_WORLD,"\nCurrent time = %f\n", user->current_time); CHKERRQ(ierr); /* c) solve the time dependent problem */ ierr = PetscTime(&v1);CHKERRQ(ierr); ierr = SNESSolve(user->snes, PETSC_NULL, algebra->solution);CHKERRQ(ierr); ierr = PetscTime(&v2);CHKERRQ(ierr); ierr = SNESGetConvergedReason(user->snes,&snesreason);CHKERRQ(ierr); if (snesreason > -1) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Solution time of %f sec, SNES converged %d (%s) \n", v2 - v1, snesreason, SNESConvergedReasons[snesreason]);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, "Solution time of %f sec, SNES diverged %d (%s).\n", v2 - v1, snesreason, SNESConvergedReasons[snesreason]);CHKERRQ(ierr); } user->current_step++; }/* end while*/ PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt its; Vec U,FU; SNES snes; UserCtx user; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); /* Create a global vector that includes a single redundant array and two da arrays */ ierr = DMCompositeCreate(PETSC_COMM_WORLD,&user.packer);CHKERRQ(ierr); ierr = DMRedundantCreate(PETSC_COMM_WORLD,0,1,&user.red1);CHKERRQ(ierr); ierr = DMCompositeAddDM(user.packer,user.red1);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-5,1,1,NULL,&user.da1);CHKERRQ(ierr); ierr = DMCompositeAddDM(user.packer,user.da1);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-5,1,1,NULL,&user.da2);CHKERRQ(ierr); ierr = DMCompositeAddDM(user.packer,user.da2);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.packer,&U);CHKERRQ(ierr); ierr = VecDuplicate(U,&FU);CHKERRQ(ierr); /* create graphics windows */ ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"u - state variables",-1,-1,-1,-1,&user.u_viewer);CHKERRQ(ierr); ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"lambda - Lagrange multipliers",-1,-1,-1,-1,&user.lambda_viewer);CHKERRQ(ierr); ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"fu - derivate w.r.t. state variables",-1,-1,-1,-1,&user.fu_viewer);CHKERRQ(ierr); ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"flambda - derivate w.r.t. Lagrange multipliers",-1,-1,-1,-1,&user.flambda_viewer);CHKERRQ(ierr); /* create nonlinear solver */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetFunction(snes,FU,FormFunction,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESMonitorSet(snes,Monitor,&user,0);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,U);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&user.red1);CHKERRQ(ierr); ierr = DMDestroy(&user.da1);CHKERRQ(ierr); ierr = DMDestroy(&user.da2);CHKERRQ(ierr); ierr = DMDestroy(&user.packer);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = VecDestroy(&FU);CHKERRQ(ierr); ierr = PetscViewerDestroy(&user.u_viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&user.lambda_viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&user.fu_viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&user.flambda_viewer);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
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); };
// ------------------------------------------------------------- // PetscNonlinearSolverImplementation::p_build // ------------------------------------------------------------- void PetscNonlinearSolverImplementation::p_build(const std::string& option_prefix) { PetscErrorCode ierr(0); try { ierr = SNESCreate(this->communicator(), &p_snes); CHKERRXX(ierr); p_petsc_F = PETScVector(*p_F); if (!p_function.empty()) { ierr = SNESSetFunction(p_snes, *p_petsc_F, FormFunction, static_cast<void *>(this)); CHKERRXX(ierr); } p_petsc_J = PETScMatrix(*p_J); if (!p_jacobian.empty()) { ierr = SNESSetJacobian(p_snes, *p_petsc_J, *p_petsc_J, FormJacobian, static_cast<void *>(this)); CHKERRXX(ierr); } // set the ierr = SNESSetOptionsPrefix(p_snes, option_prefix.c_str()); CHKERRXX(ierr); KSP ksp; ierr = SNESGetKSP(p_snes, &ksp); CHKERRXX(ierr); ierr = KSPSetOptionsPrefix(ksp, option_prefix.c_str()); CHKERRXX(ierr); PC pc; ierr = KSPGetPC(ksp, &pc); CHKERRXX(ierr); ierr = PCSetOptionsPrefix(pc, option_prefix.c_str()); CHKERRXX(ierr); ierr = SNESMonitorSet(p_snes, MonitorNorms, PETSC_NULL, PETSC_NULL); CHKERRXX(ierr); ierr = SNESSetTolerances(p_snes, p_functionTolerance, PETSC_DEFAULT, p_solutionTolerance, p_maxIterations, PETSC_DEFAULT); ierr = SNESSetFromOptions(p_snes); CHKERRXX(ierr); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } }
/*@C SNESMonitorSetRatio - Sets SNES to use a monitor that prints the ratio of the function norm at each iteration. Collective on SNES Input Parameters: + snes - the SNES context - viewer - ASCII viewer to print output Level: intermediate .keywords: SNES, nonlinear, monitor, norm .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() @*/ PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewer viewer) { PetscErrorCode ierr; SNESMonitorRatioContext *ctx; PetscReal *history; PetscFunctionBegin; ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr); ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr); if (!history) { ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr); ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); } ctx->viewer = viewer; ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); PetscFunctionReturn(0); }
/** Solves the steady-state problem, with d/dt terms 0. How well this works is debatable - for structure-only problems it works, but for fluid I'm doubtful. @param ctx my application context */ PetscErrorCode SolveSteadyState(void* ctx) { User user = (User)ctx; Algebra algebra = user->algebra; PetscMPIInt rank, size; PetscErrorCode ierr; PetscLogDouble v1, v2; SNESConvergedReason snesreason; PetscFunctionBegin; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Solving steady-state problem\n");CHKERRQ(ierr); ierr = SNESMonitorSet(user->snes, MonitorFunction, (void*) user, PETSC_NULL);CHKERRQ(ierr); ierr = PetscTime(&v1);CHKERRQ(ierr); /* solving */ ierr = SNESSolve(user->snes, PETSC_NULL, algebra->solution);CHKERRQ(ierr); // Vec func; // ierr = SNESGetFunction(user->snes,&func,0,0);CHKERRQ(ierr); // VecView(func,PETSC_VIEWER_STDOUT_WORLD); ierr = SNESGetConvergedReason(user->snes,&snesreason);CHKERRQ(ierr); ierr = PetscTime(&v2);CHKERRQ(ierr); if (snesreason > -1) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Solution time of %f sec, SNES converged %d (%s) \n", v2 - v1, snesreason, SNESConvergedReasons[snesreason]);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, "Solution time of %f sec, SNES diverged %d (%s).\n", v2 - v1, snesreason, SNESConvergedReasons[snesreason]);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode SNESSetFromOptions_VI(SNES snes) { PetscErrorCode ierr; PetscBool flg; SNESLineSearch linesearch; PetscFunctionBegin; ierr = PetscOptionsHead("SNES VI options");CHKERRQ(ierr); ierr = PetscOptionsBool("-snes_vi_monitor","Monitor all non-active variables","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); if (flg) { ierr = SNESMonitorSet(snes,SNESMonitorVI,0,0);CHKERRQ(ierr); } if (!snes->linesearch) { ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr); ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHBT);CHKERRQ(ierr); ierr = SNESLineSearchBTSetAlpha(linesearch, 0.0);CHKERRQ(ierr); } ierr = PetscOptionsTail();CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C SNESMonitorSetRatio - Sets SNES to use a monitor that prints the ratio of the function norm at each iteration. Collective on SNES Input Parameters: + snes - the SNES context - viewer - ASCII viewer to print output Level: intermediate .keywords: SNES, nonlinear, monitor, norm .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() @*/ PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewer viewer) { PetscErrorCode ierr; SNESMonitorRatioContext *ctx; PetscReal *history; PetscFunctionBegin; if (!viewer) { ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,"stdout",&viewer);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); } ierr = PetscNewLog(snes,SNESMonitorRatioContext,&ctx);CHKERRQ(ierr); ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); if (!history) { ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr); ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); } ctx->viewer = viewer; ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); PetscFunctionReturn(0); }
void PetscOutput::solveSetup() { // Only execute if PETSc exists #ifdef LIBMESH_HAVE_PETSC // Extract the non-linear and linear solvers from PETSc NonlinearSystem & nl = _problem_ptr->getNonlinearSystem(); PetscNonlinearSolver<Number> * petsc_solver = dynamic_cast<PetscNonlinearSolver<Number> *>(nl.sys().nonlinear_solver.get()); SNES snes = petsc_solver->snes(); KSP ksp; SNESGetKSP(snes, &ksp); // Update the pseudo times _nonlinear_time = _time_old; // non-linear time starts with the previous time step if (_dt != 0) _nonlinear_dt = _dt/_nonlinear_dt_divisor; // set the pseudo non-linear timestep as fraction of real timestep for transient executioners else _nonlinear_dt = 1./_nonlinear_dt_divisor; // set the pseudo non-linear timestep for steady executioners (here _dt==0) _linear_dt = _nonlinear_dt/_linear_dt_divisor; // set the pseudo linear timestep // Set the PETSc monitor functions if (_output_on.contains(EXEC_NONLINEAR) && (_time >= _nonlinear_start_time - _t_tol && _time <= _nonlinear_end_time + _t_tol) ) { PetscErrorCode ierr = SNESMonitorSet(snes, petscNonlinearOutput, this, PETSC_NULL); CHKERRABORT(_communicator.get(),ierr); } if (_output_on.contains(EXEC_LINEAR) && (_time >= _linear_start_time - _t_tol && _time <= _linear_end_time + _t_tol) ) { PetscErrorCode ierr = KSPMonitorSet(ksp, petscLinearOutput, this, PETSC_NULL); CHKERRABORT(_communicator.get(),ierr); } #endif }
void PetscNonlinearSolver<T>::init () { // Initialize the data structures if not done so already. if (!this->initialized()) { this->_is_initialized = true; PetscErrorCode ierr=0; #if PETSC_VERSION_LESS_THAN(2,1,2) // At least until Petsc 2.1.1, the SNESCreate had a different calling syntax. // The second argument was of type SNESProblemType, and could have a value of // either SNES_NONLINEAR_EQUATIONS or SNES_UNCONSTRAINED_MINIMIZATION. ierr = SNESCreate(this->comm().get(), SNES_NONLINEAR_EQUATIONS, &_snes); LIBMESH_CHKERRABORT(ierr); #else ierr = SNESCreate(this->comm().get(),&_snes); LIBMESH_CHKERRABORT(ierr); #endif #if PETSC_VERSION_LESS_THAN(2,3,3) ierr = SNESSetMonitor (_snes, __libmesh_petsc_snes_monitor, this, PETSC_NULL); #else // API name change in PETSc 2.3.3 ierr = SNESMonitorSet (_snes, __libmesh_petsc_snes_monitor, this, PETSC_NULL); #endif LIBMESH_CHKERRABORT(ierr); #if PETSC_VERSION_LESS_THAN(3,1,0) // Cannot call SNESSetOptions before SNESSetFunction when using // any matrix free options with PETSc 3.1.0+ ierr = SNESSetFromOptions(_snes); LIBMESH_CHKERRABORT(ierr); #endif if(this->_preconditioner) { KSP ksp; ierr = SNESGetKSP (_snes, &ksp); LIBMESH_CHKERRABORT(ierr); PC pc; ierr = KSPGetPC(ksp,&pc); LIBMESH_CHKERRABORT(ierr); this->_preconditioner->init(); PCSetType(pc, PCSHELL); PCShellSetContext(pc,(void*)this->_preconditioner); //Re-Use the shell functions from petsc_linear_solver PCShellSetSetUp(pc,__libmesh_petsc_preconditioner_setup); PCShellSetApply(pc,__libmesh_petsc_preconditioner_apply); } } }
int main(int argc,char **argv) { SNES snes; /* nonlinear solver context */ Vec x,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscErrorCode ierr; PetscScalar *xx; PetscInt i,max_snes_solves = 20,snes_steps_per_solve = 2,criteria_reduce = 1; Ctx ctx; SNESConvergedReason reason; PetscInitialize(&argc,&argv,(char*)0,help); ctx.n = 0; ierr = PetscOptionsGetInt(NULL,"-n",&ctx.n,NULL);CHKERRQ(ierr); ctx.p = 0; ierr = PetscOptionsGetInt(NULL,"-p",&ctx.p,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-max_snes_solves",&max_snes_solves,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-snes_steps_per_solve",&snes_steps_per_solve,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-criteria_reduce",&criteria_reduce,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix and vector data structures; set corresponding routines - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create vectors for solution and nonlinear function */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,2+ctx.n+ctx.p);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* Create Jacobian matrix data structure */ ierr = MatCreate(PETSC_COMM_WORLD,&J);CHKERRQ(ierr); ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,2+ctx.p+ctx.n,2+ctx.p+ctx.n);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = MatSetUp(J);CHKERRQ(ierr); /* Set function evaluation routine and vector. */ ierr = SNESSetFunction(snes,r,FormFunction1,(void*)&ctx);CHKERRQ(ierr); /* Set Jacobian matrix data structure and Jacobian evaluation routine */ ierr = SNESSetJacobian(snes,J,J,FormJacobian1,(void*)&ctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Evaluate initial guess; then solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecSet(x,0.0);CHKERRQ(ierr); ierr = VecGetArray(x,&xx);CHKERRQ(ierr); xx[0] = -1.2; for (i=1; i<ctx.p+2; i++) xx[i] = 1.0; ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); /* Note: The user should initialize the vector, x, with the initial guess for the nonlinear solver prior to calling SNESSolve(). In particular, to employ an initial guess of zero, the user should explicitly set this vector to zero by calling VecSet(). */ ierr = SNESMonitorSet(snes,MonitorRange,0,0);CHKERRQ(ierr); ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,snes_steps_per_solve,PETSC_DEFAULT);CHKERRQ(ierr); for (i=0; i<max_snes_solves; i++) { ierr = SNESSolve(snes,NULL,x);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); if (reason && reason != SNES_DIVERGED_MAX_IT) break; if (CountGood > criteria_reduce) { ierr = SolveSubproblem(snes);CHKERRQ(ierr); CountGood = 0; } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 = MatDestroy(&J);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
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; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 = SNESMonitorSet(ts_snes,MySNESMonitor,NULL,NULL); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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); }
int main(int argc,char **argv) { SNES snes; /* SNES context */ Vec x,r,F,U; /* vectors */ Mat J; /* Jacobian matrix */ MonitorCtx monP; /* monitoring context */ PetscErrorCode ierr; PetscInt its,n = 5,i,maxit,maxf; PetscMPIInt size; PetscScalar h,xp,v,none = -1.0; PetscReal abstol,rtol,stol,norm; PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This is a uniprocessor example only!"); ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); h = 1.0/(n-1); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create vector data structures; set function evaluation routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Note that we form 1 vector from scratch and then duplicate as needed. */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); ierr = VecDuplicate(x,&F);CHKERRQ(ierr); ierr = VecDuplicate(x,&U);CHKERRQ(ierr); /* Set function evaluation routine and vector */ ierr = SNESSetFunction(snes,r,FormFunction,(void*)F);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix data structure; set Jacobian evaluation routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&J);CHKERRQ(ierr); ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(J,3,NULL);CHKERRQ(ierr); /* Set Jacobian matrix data structure and default Jacobian evaluation routine. User can override with: -snes_fd : default finite differencing approximation of Jacobian -snes_mf : matrix-free Newton-Krylov method with no preconditioning (unless user explicitly sets preconditioner) -snes_mf_operator : form preconditioning matrix as set by the user, but use matrix-free approx for Jacobian-vector products within Newton-Krylov method */ ierr = SNESSetJacobian(snes,J,J,FormJacobian,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Set an optional user-defined monitoring routine */ ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,0,0,0,400,400,&monP.viewer);CHKERRQ(ierr); ierr = SNESMonitorSet(snes,Monitor,&monP,0);CHKERRQ(ierr); /* Set names for some vectors to facilitate monitoring (optional) */ ierr = PetscObjectSetName((PetscObject)x,"Approximate Solution");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)U,"Exact Solution");CHKERRQ(ierr); /* Set SNES/KSP/KSP/PC runtime options, e.g., -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc> */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* Print parameters used for convergence testing (optional) ... just to demonstrate this routine; this information is also printed with the option -snes_view */ ierr = SNESGetTolerances(snes,&abstol,&rtol,&stol,&maxit,&maxf);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"atol=%G, rtol=%G, stol=%G, maxit=%D, maxf=%D\n",abstol,rtol,stol,maxit,maxf);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize application: Store right-hand-side of PDE and exact solution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ xp = 0.0; for (i=0; i<n; i++) { v = 6.0*xp + PetscPowScalar(xp+1.e-12,6.0); /* +1.e-12 is to prevent 0^6 */ ierr = VecSetValues(F,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); v = xp*xp*xp; ierr = VecSetValues(U,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); xp += h; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Evaluate initial guess; then solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Note: The user should initialize the vector, x, with the initial guess for the nonlinear solver prior to calling SNESSolve(). In particular, to employ an initial guess of zero, the user should explicitly set this vector to zero by calling VecSet(). */ ierr = FormInitialGuess(x);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,x);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"number of SNES iterations = %D\n\n",its);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Check solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Check the error */ ierr = VecAXPY(x,none,U);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %G, Iterations %D\n",norm,its);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 = VecDestroy(&U);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscViewerDestroy(&monP.viewer);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }