int main(int argc,char **argv) { PetscErrorCode ierr; AppCtx ctx; TS ts; Vec tsrhs,U; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = VecCreateMPI(PETSC_COMM_WORLD,PETSC_DECIDE,1,&tsrhs);CHKERRQ(ierr); ierr = VecCreateMPI(PETSC_COMM_WORLD,PETSC_DECIDE,1,&U);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,tsrhs,TSFunction,&ctx);CHKERRQ(ierr); ctx.f = f; ierr = SNESCreate(PETSC_COMM_WORLD,&ctx.snes);CHKERRQ(ierr); ierr = SNESSetFromOptions(ctx.snes);CHKERRQ(ierr); ierr = SNESSetFunction(ctx.snes,NULL,SNESFunction,&ctx);CHKERRQ(ierr); ierr = SNESSetJacobian(ctx.snes,NULL,NULL,SNESComputeJacobianDefault,&ctx);CHKERRQ(ierr); ctx.F = F; ierr = VecCreateMPI(PETSC_COMM_WORLD,PETSC_DECIDE,1,&ctx.V);CHKERRQ(ierr); ierr = VecSet(U,1.0);CHKERRQ(ierr); ierr = TSSolve(ts,U);CHKERRQ(ierr); ierr = VecDestroy(&ctx.V);CHKERRQ(ierr); ierr = VecDestroy(&tsrhs);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = SNESDestroy(&ctx.snes);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; // nonlinear solver context Vec x, r; // solution, residual vectors PetscReal x0 = 2.0; PetscInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","options to atan","");CHKERRQ(ierr); ierr = PetscOptionsReal("-x0","initial value","atan.c",x0,&x0,NULL); CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&x); CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,1); CHKERRQ(ierr); ierr = VecSetFromOptions(x); CHKERRQ(ierr); ierr = VecSet(x,x0); CHKERRQ(ierr); ierr = VecDuplicate(x,&r); CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes); CHKERRQ(ierr); ierr = SNESSetFunction(snes,r,FormFunction,NULL); CHKERRQ(ierr); ierr = SNESSetFromOptions(snes); CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,x); CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); VecDestroy(&x); VecDestroy(&r); SNESDestroy(&snes); PetscFinalize(); return 0; }
/*@C TaoAppDefaultComputeHessian - Computes the Hessian using finite differences. Collective on TAO_APPLICATION Input Parameters: + taoapp - the TAO_APPLICATION context . V - compute Hessian at this point - ctx - the TAO_APPLICATION structure, cast to (void*) Output Parameters: + H - Hessian matrix (not altered in this routine) . B - newly computed Hessian matrix to use with preconditioner (generally the same as H) - flag - flag indicating whether the matrix sparsity structure has changed Options Database Key: + -tao_fd - Activates TaoAppDefaultComputeHessian() - -tao_view_hessian - view the hessian after each evaluation using PETSC_VIEWER_STDOUT_WORLD Level: intermediate Notes: This routine is slow and expensive, and is not currently optimized to take advantage of sparsity in the problem. Although TaoAppDefaultComputeHessian() is not recommended for general use in large-scale applications, It can be useful in checking the correctness of a user-provided Hessian. Note: The gradient evaluation must be set using the routine TaoAppSetGradientRoutine(). .keywords: TAO_APPLICATION, finite differences, Hessian .seealso: TaoAppSetHessianRoutine(), TaoAppDefaultComputeHessianColor(), SNESDefaultComputeJacobian(), TaoAppSetGradientRoutine(), TaoAppDefaultComputeGradient() @*/ int TaoAppDefaultComputeHessian(TAO_APPLICATION taoapp,Vec V,Mat *H,Mat *B, MatStructure *flag,void *ctx){ int info; MPI_Comm comm; Vec G; SNES snes; TAO_SOLVER tao; PetscFunctionBegin; info = TaoAppGetTaoSolver(taoapp, &tao); PetscValidHeaderSpecific(V,VEC_COOKIE,2); info = VecDuplicate(V,&G);CHKERRQ(info); info = PetscInfo(G,"TAO Using finite differences w/o coloring to compute matrix\n"); CHKERRQ(info); info = TaoAppComputeGradient(taoapp,V,G); CHKERRQ(info); tao->ngrads++; info = PetscObjectGetComm((PetscObject)(*H),&comm);CHKERRQ(info); info = SNESCreate(comm,&snes);CHKERRQ(info); info = SNESSetFunction(snes,G,Ftemp,taoapp);CHKERRQ(info); info = SNESDefaultComputeJacobian(snes,V,H,B,flag,taoapp);CHKERRQ(info); info = SNESDestroy(snes);CHKERRQ(info); info = VecDestroy(G);CHKERRQ(info); PetscFunctionReturn(0); }
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; }
unsigned int PetscDiffSolver::solve() { this->init(); START_LOG("solve()", "PetscDiffSolver"); PetscVector<Number> &x = *(libmesh_cast_ptr<PetscVector<Number>*>(_system.solution.get())); PetscMatrix<Number> &jac = *(libmesh_cast_ptr<PetscMatrix<Number>*>(_system.matrix)); PetscVector<Number> &r = *(libmesh_cast_ptr<PetscVector<Number>*>(_system.rhs)); #ifdef LIBMESH_ENABLE_CONSTRAINTS _system.get_dof_map().enforce_constraints_exactly(_system); #endif int ierr = 0; ierr = SNESSetFunction (_snes, r.vec(), __libmesh_petsc_diff_solver_residual, this); LIBMESH_CHKERRABORT(ierr); ierr = SNESSetJacobian (_snes, jac.mat(), jac.mat(), __libmesh_petsc_diff_solver_jacobian, this); LIBMESH_CHKERRABORT(ierr); # if PETSC_VERSION_LESS_THAN(2,2,0) ierr = SNESSolve (_snes, x.vec(), &_outer_iterations); LIBMESH_CHKERRABORT(ierr); // 2.2.x style #elif PETSC_VERSION_LESS_THAN(2,3,0) ierr = SNESSolve (_snes, x.vec()); LIBMESH_CHKERRABORT(ierr); // 2.3.x & newer style #else ierr = SNESSolve (_snes, PETSC_NULL, x.vec()); LIBMESH_CHKERRABORT(ierr); #endif STOP_LOG("solve()", "PetscDiffSolver"); SNESConvergedReason reason; SNESGetConvergedReason(_snes, &reason); this->clear(); return convert_solve_result(reason); }
unsigned int PetscDiffSolver::solve() { this->init(); START_LOG("solve()", "PetscDiffSolver"); PetscVector<Number> &x = *(libmesh_cast_ptr<PetscVector<Number>*>(_system.solution.get())); PetscMatrix<Number> &jac = *(libmesh_cast_ptr<PetscMatrix<Number>*>(_system.matrix)); PetscVector<Number> &r = *(libmesh_cast_ptr<PetscVector<Number>*>(_system.rhs)); #ifdef LIBMESH_ENABLE_CONSTRAINTS _system.get_dof_map().enforce_constraints_exactly(_system); #endif int ierr = 0; ierr = SNESSetFunction (_snes, r.vec(), __libmesh_petsc_diff_solver_residual, this); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = SNESSetJacobian (_snes, jac.mat(), jac.mat(), __libmesh_petsc_diff_solver_jacobian, this); CHKERRABORT(libMesh::COMM_WORLD,ierr); # if PETSC_VERSION_LESS_THAN(2,2,0) ierr = SNESSolve (_snes, x.vec(), &_outer_iterations); CHKERRABORT(libMesh::COMM_WORLD,ierr); // 2.2.x style #elif PETSC_VERSION_LESS_THAN(2,3,0) ierr = SNESSolve (_snes, x.vec()); CHKERRABORT(libMesh::COMM_WORLD,ierr); // 2.3.x & newer style #else ierr = SNESSolve (_snes, PETSC_NULL, x.vec()); CHKERRABORT(libMesh::COMM_WORLD,ierr); #endif STOP_LOG("solve()", "PetscDiffSolver"); this->clear(); // FIXME - We'll worry about getting the solve result right later... return DiffSolver::CONVERGED_RELATIVE_RESIDUAL; }
int main(int argc, char **argv) { SNES snes; /* nonlinear solver */ Mat A,J; /* Jacobian,preconditioner matrix */ Vec u,r; /* solution, residual vectors */ AppCtx user; /* user-defined work context */ PetscReal error = 0.0; /* L_2 error in the solution */ PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, PETSC_NULL, help);CHKERRQ(ierr); ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &user.dm);CHKERRQ(ierr); ierr = SNESSetDM(snes, user.dm);CHKERRQ(ierr); ierr = SetupSection(user.dm, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.dm, &u);CHKERRQ(ierr); ierr = VecDuplicate(u, &r);CHKERRQ(ierr); ierr = DMCreateMatrix(user.dm, MATAIJ, &J);CHKERRQ(ierr); A = J; ierr = DMSetLocalFunction(user.dm, (DMLocalFunction1) FormFunctionLocal);CHKERRQ(ierr); ierr = DMSetLocalJacobian(user.dm, (DMLocalJacobian1) FormJacobianLocal);CHKERRQ(ierr); ierr = SNESSetFunction(snes, r, SNESDMComputeFunction, &user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes, A, J, SNESDMComputeJacobian, &user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); { PetscReal res; /* Check discretization error */ ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial guess\n");CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* ierr = ComputeError(u, &error, &user);CHKERRQ(ierr); */ ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Error: %g\n", error);CHKERRQ(ierr); /* Check residual */ ierr = SNESDMComputeFunction(snes, u, r, &user);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial Residual\n");CHKERRQ(ierr); ierr = VecChop(r, 1.0e-10);CHKERRQ(ierr); ierr = VecView(r, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecNorm(r, NORM_2, &res);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Residual: %g\n", res);CHKERRQ(ierr); } ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&user.dm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; AppCtx ctx; TS ts; Vec tsrhs,U; IS is; PetscInt I; PetscMPIInt rank; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = VecCreateMPI(PETSC_COMM_WORLD,1,PETSC_DETERMINE,&tsrhs);CHKERRQ(ierr); ierr = VecCreateMPI(PETSC_COMM_WORLD,1,PETSC_DETERMINE,&U);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,tsrhs,TSFunction,&ctx);CHKERRQ(ierr); ctx.f = f; ierr = SNESCreate(PETSC_COMM_WORLD,&ctx.snes);CHKERRQ(ierr); ierr = SNESSetFromOptions(ctx.snes);CHKERRQ(ierr); ierr = SNESSetFunction(ctx.snes,NULL,SNESFunction,&ctx);CHKERRQ(ierr); ierr = SNESSetJacobian(ctx.snes,NULL,NULL,SNESComputeJacobianDefault,&ctx);CHKERRQ(ierr); ctx.F = F; ierr = VecCreateMPI(PETSC_COMM_WORLD,1,PETSC_DETERMINE,&ctx.V);CHKERRQ(ierr); /* Create scatters to move between separate U and V representation and UV representation of solution */ ierr = VecCreateMPI(PETSC_COMM_WORLD,2,PETSC_DETERMINE,&ctx.UV);CHKERRQ(ierr); I = 2*rank; ierr = ISCreateGeneral(PETSC_COMM_WORLD,1,&I,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); ierr = VecScatterCreateWithData(U,NULL,ctx.UV,is,&ctx.scatterU);CHKERRQ(ierr); ierr = ISDestroy(&is);CHKERRQ(ierr); I = 2*rank + 1; ierr = ISCreateGeneral(PETSC_COMM_WORLD,1,&I,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); ierr = VecScatterCreateWithData(ctx.V,NULL,ctx.UV,is,&ctx.scatterV);CHKERRQ(ierr); ierr = ISDestroy(&is);CHKERRQ(ierr); ierr = VecSet(U,1.0);CHKERRQ(ierr); ierr = TSSolve(ts,U);CHKERRQ(ierr); ierr = VecDestroy(&ctx.V);CHKERRQ(ierr); ierr = VecDestroy(&ctx.UV);CHKERRQ(ierr); ierr = VecScatterDestroy(&ctx.scatterU);CHKERRQ(ierr); ierr = VecScatterDestroy(&ctx.scatterV);CHKERRQ(ierr); ierr = VecDestroy(&tsrhs);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = SNESDestroy(&ctx.snes);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
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 consistency_test(NdArray<const T> x, const T small, const T rtol, const T atol, const int steps) const { // Build vector GEODE_ASSERT(x.shape==xshape); const auto v = vector(); reduce(x.flat,RawVec<T>(v->v)); // Build an SNES object const auto snes = new_<SNES>(PETSC_COMM_SELF); CHECK(SNESSetObjective(snes->snes,value<::SNES>,(void*)this)); CHECK(SNESSetFunction(snes->snes,v->v,gradient<::SNES>,(void*)this)); // Test snes->consistency_test(v,small,rtol,atol,steps); }
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); };
int main(int argc,char **argv) { SNES snes; Vec x,f; Mat J; DA da; PetscInitialize(&argc,&argv,(char *)0,help); DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,8,1,1,PETSC_NULL,&da); DACreateGlobalVector(da,&x); VecDuplicate(x,&f); DAGetMatrix(da,MATAIJ,&J); SNESCreate(PETSC_COMM_WORLD,&snes); SNESSetFunction(snes,f,ComputeFunction,da); SNESSetJacobian(snes,J,J,ComputeJacobian,da); SNESSetFromOptions(snes); SNESSolve(snes,PETSC_NULL,x); MatDestroy(J); VecDestroy(x); VecDestroy(f); SNESDestroy(snes); DADestroy(da); PetscFinalize(); return 0;}
// ------------------------------------------------------------- // 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); } }
int main(int argc, char** argv) { PetscInitialize( &argc, &argv, (char *)0, 0 ) ; int ncpus; MPI_Comm_size(PETSC_COMM_WORLD,&ncpus); if (ncpus > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "Example is only for sequential runs"); Vec x, r; VecCreate(PETSC_COMM_WORLD, &x); VecSetSizes(x, PETSC_DECIDE, 2); VecSetFromOptions(x); VecDuplicate(x, &r); Mat J; MatCreate(PETSC_COMM_WORLD, &J); MatSetSizes(J, PETSC_DECIDE, PETSC_DECIDE, 2, 2); MatSetFromOptions(J); MatSetUp(J); SNES snes; SNESCreate(PETSC_COMM_WORLD, &snes); SNESSetFunction(snes, r, CalculateFunc, NULL); SNESSetJacobian(snes, J, J, CalculateJacobian, NULL); SNESSetFromOptions(snes); VecSet(x, 1.0); SNESSolve(snes, NULL, x); VecView(x,PETSC_VIEWER_STDOUT_WORLD); SNESGetFunction(snes,&r,0,0); VecView(r,PETSC_VIEWER_STDOUT_WORLD); SNESDestroy(&snes); MatDestroy(&J); VecDestroy(&r); VecDestroy(&x); PetscFinalize(); return 0; }
int main(int argc,char **argv) { SNES snes; /* nonlinear solver context */ Vec r; /* solution, residual vectors */ PetscErrorCode ierr; AppCtx user; /* user-defined work context */ PetscViewer viewer; PetscInitialize(&argc,&argv,(char*)0,help); ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,"videfinition",FILE_MODE_READ,&viewer);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&user.M);CHKERRQ(ierr); ierr = MatLoad(user.M,viewer);CHKERRQ(ierr); ierr = MatDuplicate(user.M,MAT_COPY_VALUES,&user.Jac);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&user.q);CHKERRQ(ierr); ierr = VecLoad(user.q,viewer);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&user.lb);CHKERRQ(ierr); ierr = VecLoad(user.lb,viewer);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&user.ub);CHKERRQ(ierr);ierr = VecLoad(user.ub,viewer);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&user.zz);CHKERRQ(ierr);ierr = VecLoad(user.zz,viewer);CHKERRQ(ierr); ierr = VecView(user.zz,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); /* ierr = VecSet(user.zz,0.01);CHKERRQ(ierr);*/ ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecDuplicate(user.q,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetFunction(snes,r,FormFunction1,&user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,user.Jac,user.Jac,FormJacobian1,&user);CHKERRQ(ierr); ierr = SNESVISetVariableBounds(snes,user.lb,user.ub);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,user.zz);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)user.zz,"x*");CHKERRQ(ierr); ierr = VecView(user.zz,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)r,"f(x*)");CHKERRQ(ierr); ierr = FormFunction1(snes,user.zz,r,&user);CHKERRQ(ierr); ierr = VecView(r,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; // nonlinear solver context Vec x, r; // solution, residual vectors PetscInitialize(&argc,&argv,NULL,help); ierr = VecCreate(PETSC_COMM_WORLD,&x); CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,2); CHKERRQ(ierr); ierr = VecSetFromOptions(x); CHKERRQ(ierr); ierr = VecSet(x,1.0); CHKERRQ(ierr); ierr = VecDuplicate(x,&r); CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes); CHKERRQ(ierr); ierr = SNESSetFunction(snes,r,FormFunction,NULL); CHKERRQ(ierr); ierr = SNESSetFromOptions(snes); CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,x); CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); VecDestroy(&x); VecDestroy(&r); SNESDestroy(&snes); return PetscFinalize(); }
/*@C TaoDefaultComputeHessian - Computes the Hessian using finite differences. Collective on Tao Input Parameters: + tao - the Tao context . V - compute Hessian at this point - dummy - not used Output Parameters: + H - Hessian matrix (not altered in this routine) - B - newly computed Hessian matrix to use with preconditioner (generally the same as H) Options Database Key: . -tao_fd_hessian - activates TaoDefaultComputeHessian() Level: advanced Notes: This routine is slow and expensive, and is not currently optimized to take advantage of sparsity in the problem. Although TaoDefaultComputeHessian() is not recommended for general use in large-scale applications, It can be useful in checking the correctness of a user-provided Hessian. .seealso: TaoSetHessianRoutine(), TaoDefaultComputeHessianColor(), SNESComputeJacobianDefault(), TaoSetGradientRoutine(), TaoDefaultComputeGradient() @*/ PetscErrorCode TaoDefaultComputeHessian(Tao tao,Vec V,Mat H,Mat B,void *dummy) { PetscErrorCode ierr; Vec G; SNES snes; DM dm; PetscFunctionBegin; ierr = VecDuplicate(V,&G);CHKERRQ(ierr); ierr = PetscInfo(tao,"TAO Using finite differences w/o coloring to compute Hessian matrix\n");CHKERRQ(ierr); ierr = TaoComputeGradient(tao,V,G);CHKERRQ(ierr); ierr = SNESCreate(PetscObjectComm((PetscObject)H),&snes);CHKERRQ(ierr); ierr = SNESSetFunction(snes,G,Fsnes,tao);CHKERRQ(ierr); ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); ierr = DMShellSetGlobalVector(dm,V);CHKERRQ(ierr); ierr = SNESSetUp(snes);CHKERRQ(ierr); if (H) { PetscInt n,N; ierr = VecGetSize(V,&N);CHKERRQ(ierr); ierr = VecGetLocalSize(V,&n);CHKERRQ(ierr); ierr = MatSetSizes(H,n,n,N,N);CHKERRQ(ierr); ierr = MatSetUp(H);CHKERRQ(ierr); } if (B && B != H) { PetscInt n,N; ierr = VecGetSize(V,&N);CHKERRQ(ierr); ierr = VecGetLocalSize(V,&n);CHKERRQ(ierr); ierr = MatSetSizes(B,n,n,N,N);CHKERRQ(ierr); ierr = MatSetUp(B);CHKERRQ(ierr); } ierr = SNESComputeJacobianDefault(snes,V,H,B,NULL);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = VecDestroy(&G);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C TaoDefaultComputeHessian - Computes the Hessian using finite differences. Collective on Tao Input Parameters: + tao - the Tao context . V - compute Hessian at this point - dummy - not used Output Parameters: + H - Hessian matrix (not altered in this routine) - B - newly computed Hessian matrix to use with preconditioner (generally the same as H) Options Database Key: + -tao_fd - Activates TaoDefaultComputeHessian() - -tao_view_hessian - view the hessian after each evaluation using PETSC_VIEWER_STDOUT_WORLD Level: advanced Notes: This routine is slow and expensive, and is not currently optimized to take advantage of sparsity in the problem. Although TaoDefaultComputeHessian() is not recommended for general use in large-scale applications, It can be useful in checking the correctness of a user-provided Hessian. .seealso: TaoSetHessianRoutine(), TaoDefaultComputeHessianColor(), SNESComputeJacobianDefault(), TaoSetGradientRoutine(), TaoDefaultComputeGradient() @*/ PetscErrorCode TaoDefaultComputeHessian(Tao tao,Vec V,Mat H,Mat B,void *dummy) { PetscErrorCode ierr; MPI_Comm comm; Vec G; SNES snes; PetscFunctionBegin; PetscValidHeaderSpecific(V,VEC_CLASSID,2); ierr = VecDuplicate(V,&G);CHKERRQ(ierr); ierr = PetscInfo(tao,"TAO Using finite differences w/o coloring to compute Hessian matrix\n");CHKERRQ(ierr); ierr = TaoComputeGradient(tao,V,G);CHKERRQ(ierr); ierr = PetscObjectGetComm((PetscObject)H,&comm);CHKERRQ(ierr); ierr = SNESCreate(comm,&snes);CHKERRQ(ierr); ierr = SNESSetFunction(snes,G,Fsnes,tao);CHKERRQ(ierr); ierr = SNESComputeJacobianDefault(snes,V,H,B,tao);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = VecDestroy(&G);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { SNES snes; /* nonlinear solver context */ Vec x,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscErrorCode ierr; PetscInt its; PetscScalar *xx; SNESConvergedReason reason; PetscInitialize(&argc,&argv,(char *)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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);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,2);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = MatSetUp(J);CHKERRQ(ierr); /* Set function evaluation routine and vector. */ ierr = SNESSetFunction(snes,r,FormFunction1,PETSC_NULL);CHKERRQ(ierr); /* Set Jacobian matrix data structure and Jacobian evaluation routine */ ierr = SNESSetJacobian(snes,J,J,FormJacobian1,PETSC_NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Evaluate initial guess; then solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecGetArray(x,&xx);CHKERRQ(ierr); xx[0] = -1.2; xx[1] = 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 = SNESSolve(snes,PETSC_NULL,x);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); /* Some systems computes a residual that is identically zero, thus converging due to FNORM_ABS, others converge due to FNORM_RELATIVE. Here, we only report the reason if the iteration did not converge so that the tests are reproducible. */ ierr = PetscPrintf(PETSC_COMM_WORLD,"%s number of SNES iterations = %D\n\n",reason>0?"CONVERGED":SNESConvergedReasons[reason],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 = MatDestroy(&J);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 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); }
int main(int argc, char **argv) { MPI_Comm comm; PetscMPIInt rank; PetscErrorCode ierr; User user; PetscLogDouble v1, v2; PetscInt nplot = 0; char filename1[2048], fileName[2048]; PetscBool set = PETSC_FALSE; PetscInt steps_output; ierr = PetscInitialize(&argc, &argv, (char*) 0, help);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); ierr = PetscNew(&user->algebra);CHKERRQ(ierr); ierr = PetscNew(&user->model);CHKERRQ(ierr); ierr = PetscNew(&user->model->physics);CHKERRQ(ierr); Algebra algebra = user->algebra; ierr = LoadOptions(comm, user);CHKERRQ(ierr); ierr = PetscTime(&v1);CHKERRQ(ierr); ierr = CreateMesh(comm, user);CHKERRQ(ierr); ierr = PetscTime(&v2);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Read and Distribute mesh takes %f sec \n", v2 - v1);CHKERRQ(ierr); ierr = SetUpLocalSpace(user);CHKERRQ(ierr); //Set up the dofs of each element ierr = ConstructGeometryFVM(&user->facegeom, &user->cellgeom, user);CHKERRQ(ierr); ierr = LimiterSetup(user);CHKERRQ(ierr); if(user->output_solution){ // the output file options ierr = PetscOptionsBegin(PETSC_COMM_WORLD,0,"Options for output solution",0);CHKERRQ(ierr); ierr = PetscOptionsString("-solutionfile", "solution file", "AeroSim.c", filename1,filename1, 2048, &set);CHKERRQ(ierr); if(!set){SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,"please use option -solutionfile to specify solution file name \n");} ierr = PetscOptionsInt("-steps_output", "the number of time steps between two outputs", "", steps_output, &steps_output, &set);CHKERRQ(ierr); if(!set){ steps_output = 1;} ierr = PetscOptionsEnd();CHKERRQ(ierr); } if (user->TimeIntegralMethod == EXPLICITMETHOD) { if(user->myownexplicitmethod){ ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on my own routing\n");CHKERRQ(ierr); user->current_time = user->initial_time; user->current_step = 1; ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr); if(user->Explicit_RK2){ ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the second order Runge Kutta method \n");CHKERRQ(ierr); }else{ ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the first order forward Euler method \n");CHKERRQ(ierr); } nplot = 0; //the plot step while(user->current_time < (user->final_time - 0.05 * user->dt)){ user->current_time = user->current_time + user->dt; ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); PetscReal fnnorm; ierr = VecNorm(algebra->fn,NORM_INFINITY,&fnnorm);CHKERRQ(ierr); if(0){ PetscViewer viewer; ierr = OutputVTK(user->dm, "function.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->fn, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with founction norm = %g \n", user->current_step, user->current_time, fnnorm);CHKERRQ(ierr); //break; } if(user->Explicit_RK2){ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr);//U^n ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);//U^{(1)} ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);//f(U^{(1)}) ierr = VecAXPY(algebra->solution, 1.0, algebra->oldsolution);CHKERRQ(ierr);//U^n + U^{(1)} ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);// + dt*f(U^{(1)}) ierr = VecScale(algebra->solution, 0.5);CHKERRQ(ierr); }else{ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr); } {// Monitor the solution and function norms PetscReal norm; PetscLogDouble space =0; PetscInt size; ierr = VecNorm(algebra->solution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = VecGetSize(algebra->solution, &size);CHKERRQ(ierr); norm = norm/size; if (norm>1.e5) { SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_LIB, "The norm of the solution is: %f (current time: %f). The explicit method is going to DIVERGE!!!", norm, user->current_time); } if (user->current_step%10==0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with solution norm = %g and founction norm = %g \n", user->current_step, user->current_time, norm, fnnorm);CHKERRQ(ierr); } ierr = PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr); // if (user->current_step%10==0) { // ierr = PetscPrintf(PETSC_COMM_WORLD,"Current space PetscMalloc()ed %g M\n", // space/(1024*1024));CHKERRQ(ierr); // } } { // Monitor the difference of two steps' solution PetscReal norm; ierr = VecAXPY(algebra->oldsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->oldsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); if (user->current_step%10==0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with ||u_k-u_{k-1}|| = %g \n", user->current_step, user->current_time, norm);CHKERRQ(ierr); } if((norm<1.e-6)||(user->current_step > user->max_time_its)) break; } // output the solution if (user->output_solution && (user->current_step%steps_output==0)){ PetscViewer viewer; // update file name for the current time step ierr = PetscSNPrintf(fileName, sizeof(fileName),"%s_%d.vtk",filename1, nplot);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing solution %s (current time %f)\n", fileName, user->current_time);CHKERRQ(ierr); ierr = OutputVTK(user->dm, fileName, &viewer);CHKERRQ(ierr); ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); nplot++; } user->current_step++; } ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr); }else{ PetscReal ftime; TS ts; TSConvergedReason reason; PetscInt nsteps; ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on the PETSC TS routing\n");CHKERRQ(ierr); ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = TSCreate(comm, &ts);CHKERRQ(ierr); ierr = TSSetType(ts, TSEULER);CHKERRQ(ierr); ierr = TSSetDM(ts, user->dm);CHKERRQ(ierr); ierr = TSMonitorSet(ts,TSMonitorFunctionError,&user,NULL);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts, NULL, MyRHSFunction, user);CHKERRQ(ierr); ierr = TSSetDuration(ts, 1000, user->final_time);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts, user->initial_time, user->dt);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts, algebra->solution);CHKERRQ(ierr); ierr = TSGetSolveTime(ts, &ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts, &nsteps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts, &reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],ftime,nsteps);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); } if(user->benchmark_couette) { ierr = DMCreateGlobalVector(user->dm, &algebra->exactsolution);CHKERRQ(ierr); ierr = ComputeExactSolution(user->dm, user->final_time, algebra->exactsolution, user);CHKERRQ(ierr); } if (user->output_solution){ PetscViewer viewer; ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } if(user->benchmark_couette) { PetscViewer viewer; PetscReal norm; ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Final time at %f, Error: ||u_k-u|| = %g \n", user->final_time, norm);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr); ierr = DMDestroy(&user->dm);CHKERRQ(ierr); } else if (user->TimeIntegralMethod == IMPLICITMETHOD) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully implicit method\n");CHKERRQ(ierr); ierr = SNESCreate(comm,&user->snes);CHKERRQ(ierr); ierr = SNESSetDM(user->snes,user->dm);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->f);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldfn);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = DMSetMatType(user->dm, MATAIJ);CHKERRQ(ierr); // ierr = DMCreateMatrix(user->dm, &algebra->A);CHKERRQ(ierr); ierr = DMCreateMatrix(user->dm, &algebra->J);CHKERRQ(ierr); if (user->JdiffP) { /*Set up the preconditioner matrix*/ ierr = DMCreateMatrix(user->dm, &algebra->P);CHKERRQ(ierr); }else{ algebra->P = algebra->J; } ierr = MatSetOption(algebra->J, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRQ(ierr); /*set nonlinear function */ ierr = SNESSetFunction(user->snes, algebra->f, FormFunction, (void*)user);CHKERRQ(ierr); /* compute Jacobian */ ierr = SNESSetJacobian(user->snes, algebra->J, algebra->P, FormJacobian, (void*)user);CHKERRQ(ierr); ierr = SNESSetFromOptions(user->snes);CHKERRQ(ierr); /* do the solve */ if (user->timestep == TIMESTEP_STEADY_STATE) { ierr = SolveSteadyState(user);CHKERRQ(ierr); } else { ierr = SolveTimeDependent(user);CHKERRQ(ierr); } if (user->output_solution){ PetscViewer viewer; ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } if(user->benchmark_couette) { PetscViewer viewer; PetscReal norm; ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error: ||u_k-u|| = %g \n", norm);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->f);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldfn);CHKERRQ(ierr); ierr = SNESDestroy(&user->snes);CHKERRQ(ierr); ierr = DMDestroy(&user->dm);CHKERRQ(ierr); } else { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"WRONG option for the time integral method. Using the option '-time_integral_method 0 or 1'"); } ierr = VecDestroy(&user->cellgeom);CHKERRQ(ierr); ierr = VecDestroy(&user->facegeom);CHKERRQ(ierr); ierr = DMDestroy(&user->dmGrad);CHKERRQ(ierr); ierr = PetscFunctionListDestroy(&LimitList);CHKERRQ(ierr); ierr = PetscFree(user->model->physics);CHKERRQ(ierr); ierr = PetscFree(user->algebra);CHKERRQ(ierr); ierr = PetscFree(user->model);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); { PetscLogDouble space =0; ierr = PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Unfreed space at the End %g M\n", space/(1024*1024));CHKERRQ(ierr); } ierr = PetscFinalize(); return(0); }
std::pair<unsigned int, Real> PetscNonlinearSolver<T>::solve (SparseMatrix<T>& jac_in, // System Jacobian Matrix NumericVector<T>& x_in, // Solution vector NumericVector<T>& r_in, // Residual vector const double, // Stopping tolerance const unsigned int) { START_LOG("solve()", "PetscNonlinearSolver"); this->init (); // Make sure the data passed in are really of Petsc types PetscMatrix<T>* jac = libmesh_cast_ptr<PetscMatrix<T>*>(&jac_in); PetscVector<T>* x = libmesh_cast_ptr<PetscVector<T>*>(&x_in); PetscVector<T>* r = libmesh_cast_ptr<PetscVector<T>*>(&r_in); PetscErrorCode ierr=0; PetscInt n_iterations =0; // Should actually be a PetscReal, but I don't know which version of PETSc first introduced PetscReal Real final_residual_norm=0.; ierr = SNESSetFunction (_snes, r->vec(), __libmesh_petsc_snes_residual, this); LIBMESH_CHKERRABORT(ierr); // Only set the jacobian function if we've been provided with something to call. // This allows a user to set their own jacobian function if they want to if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object) { ierr = SNESSetJacobian (_snes, jac->mat(), jac->mat(), __libmesh_petsc_snes_jacobian, this); LIBMESH_CHKERRABORT(ierr); } #if !PETSC_VERSION_LESS_THAN(3,3,0) // Only set the nullspace if we have a way of computing it and the result is non-empty. if (this->nullspace || this->nullspace_object) { MatNullSpace msp; this->build_mat_null_space(this->nullspace_object, this->nullspace, &msp); if (msp) { ierr = MatSetNullSpace(jac->mat(), msp); LIBMESH_CHKERRABORT(ierr); ierr = MatNullSpaceDestroy(&msp); LIBMESH_CHKERRABORT(ierr); } } // Only set the nearnullspace if we have a way of computing it and the result is non-empty. if (this->nearnullspace || this->nearnullspace_object) { MatNullSpace msp = PETSC_NULL; this->build_mat_null_space(this->nearnullspace_object, this->nearnullspace, &msp); if(msp) { ierr = MatSetNearNullSpace(jac->mat(), msp); LIBMESH_CHKERRABORT(ierr); ierr = MatNullSpaceDestroy(&msp); LIBMESH_CHKERRABORT(ierr); } } #endif // Have the Krylov subspace method use our good initial guess rather than 0 KSP ksp; ierr = SNESGetKSP (_snes, &ksp); LIBMESH_CHKERRABORT(ierr); // Set the tolerances for the iterative solver. Use the user-supplied // tolerance for the relative residual & leave the others at default values ierr = KSPSetTolerances (ksp, this->initial_linear_tolerance, PETSC_DEFAULT, PETSC_DEFAULT, this->max_linear_iterations); LIBMESH_CHKERRABORT(ierr); // Set the tolerances for the non-linear solver. ierr = SNESSetTolerances(_snes, this->absolute_residual_tolerance, this->relative_residual_tolerance, this->relative_step_tolerance, this->max_nonlinear_iterations, this->max_function_evaluations); LIBMESH_CHKERRABORT(ierr); //Pull in command-line options KSPSetFromOptions(ksp); SNESSetFromOptions(_snes); if (this->user_presolve) this->user_presolve(this->system()); //Set the preconditioning matrix if(this->_preconditioner) { this->_preconditioner->set_matrix(jac_in); this->_preconditioner->init(); } // ierr = KSPSetInitialGuessNonzero (ksp, PETSC_TRUE); // LIBMESH_CHKERRABORT(ierr); // Older versions (at least up to 2.1.5) of SNESSolve took 3 arguments, // the last one being a pointer to an int to hold the number of iterations required. # if PETSC_VERSION_LESS_THAN(2,2,0) ierr = SNESSolve (_snes, x->vec(), &n_iterations); LIBMESH_CHKERRABORT(ierr); // 2.2.x style #elif PETSC_VERSION_LESS_THAN(2,3,0) ierr = SNESSolve (_snes, x->vec()); LIBMESH_CHKERRABORT(ierr); // 2.3.x & newer style #else ierr = SNESSolve (_snes, PETSC_NULL, x->vec()); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetIterationNumber(_snes,&n_iterations); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetLinearSolveIterations(_snes, &_n_linear_iterations); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetFunctionNorm(_snes,&final_residual_norm); LIBMESH_CHKERRABORT(ierr); #endif // Get and store the reason for convergence SNESGetConvergedReason(_snes, &_reason); //Based on Petsc 2.3.3 documentation all diverged reasons are negative this->converged = (_reason >= 0); this->clear(); STOP_LOG("solve()", "PetscNonlinearSolver"); // return the # of its. and the final residual norm. return std::make_pair(n_iterations, final_residual_norm); }
int main(int argc,char ** argv) { PetscErrorCode ierr; char pfdata_file[PETSC_MAX_PATH_LEN]="datafiles/case9.m"; PFDATA *pfdata; PetscInt numEdges=0,numVertices=0; int *edges = NULL; PetscInt i; DM networkdm; PetscInt componentkey[4]; UserCtx User; PetscLogStage stage1,stage2; PetscMPIInt size,rank; PetscInt eStart, eEnd, vStart, vEnd,j; PetscInt genj,loadj; Vec X,F; Mat J; SNES snes; ierr = PetscInitialize(&argc,&argv,"pfoptions",help);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); { /* introduce the const crank so the clang static analyzer realizes that if it enters any of the if (crank) then it must have entered the first */ /* this is an experiment to see how the analyzer reacts */ const PetscMPIInt crank = rank; /* Create an empty network object */ ierr = DMNetworkCreate(PETSC_COMM_WORLD,&networkdm);CHKERRQ(ierr); /* Register the components in the network */ ierr = DMNetworkRegisterComponent(networkdm,"branchstruct",sizeof(struct _p_EDGEDATA),&componentkey[0]);CHKERRQ(ierr); ierr = DMNetworkRegisterComponent(networkdm,"busstruct",sizeof(struct _p_VERTEXDATA),&componentkey[1]);CHKERRQ(ierr); ierr = DMNetworkRegisterComponent(networkdm,"genstruct",sizeof(struct _p_GEN),&componentkey[2]);CHKERRQ(ierr); ierr = DMNetworkRegisterComponent(networkdm,"loadstruct",sizeof(struct _p_LOAD),&componentkey[3]);CHKERRQ(ierr); ierr = PetscLogStageRegister("Read Data",&stage1);CHKERRQ(ierr); PetscLogStagePush(stage1); /* READ THE DATA */ if (!crank) { /* READ DATA */ /* Only rank 0 reads the data */ ierr = PetscOptionsGetString(NULL,NULL,"-pfdata",pfdata_file,PETSC_MAX_PATH_LEN-1,NULL);CHKERRQ(ierr); ierr = PetscNew(&pfdata);CHKERRQ(ierr); ierr = PFReadMatPowerData(pfdata,pfdata_file);CHKERRQ(ierr); User.Sbase = pfdata->sbase; numEdges = pfdata->nbranch; numVertices = pfdata->nbus; ierr = PetscMalloc(2*numEdges*sizeof(int),&edges);CHKERRQ(ierr); ierr = GetListofEdges(pfdata->nbranch,pfdata->branch,edges);CHKERRQ(ierr); } PetscLogStagePop(); ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); ierr = PetscLogStageRegister("Create network",&stage2);CHKERRQ(ierr); PetscLogStagePush(stage2); /* Set number of nodes/edges */ ierr = DMNetworkSetSizes(networkdm,numVertices,numEdges,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); /* Add edge connectivity */ ierr = DMNetworkSetEdgeList(networkdm,edges);CHKERRQ(ierr); /* Set up the network layout */ ierr = DMNetworkLayoutSetUp(networkdm);CHKERRQ(ierr); if (!crank) { ierr = PetscFree(edges);CHKERRQ(ierr); } /* Add network components only process 0 has any data to add*/ if (!crank) { genj=0; loadj=0; ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr); for (i = eStart; i < eEnd; i++) { ierr = DMNetworkAddComponent(networkdm,i,componentkey[0],&pfdata->branch[i-eStart]);CHKERRQ(ierr); } ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr); for (i = vStart; i < vEnd; i++) { ierr = DMNetworkAddComponent(networkdm,i,componentkey[1],&pfdata->bus[i-vStart]);CHKERRQ(ierr); if (pfdata->bus[i-vStart].ngen) { for (j = 0; j < pfdata->bus[i-vStart].ngen; j++) { ierr = DMNetworkAddComponent(networkdm,i,componentkey[2],&pfdata->gen[genj++]);CHKERRQ(ierr); } } if (pfdata->bus[i-vStart].nload) { for (j=0; j < pfdata->bus[i-vStart].nload; j++) { ierr = DMNetworkAddComponent(networkdm,i,componentkey[3],&pfdata->load[loadj++]);CHKERRQ(ierr); } } /* Add number of variables */ ierr = DMNetworkAddNumVariables(networkdm,i,2);CHKERRQ(ierr); } } /* Set up DM for use */ ierr = DMSetUp(networkdm);CHKERRQ(ierr); if (!crank) { ierr = PetscFree(pfdata->bus);CHKERRQ(ierr); ierr = PetscFree(pfdata->gen);CHKERRQ(ierr); ierr = PetscFree(pfdata->branch);CHKERRQ(ierr); ierr = PetscFree(pfdata->load);CHKERRQ(ierr); ierr = PetscFree(pfdata);CHKERRQ(ierr); } ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) { DM distnetworkdm; /* Network partitioning and distribution of data */ ierr = DMNetworkDistribute(networkdm,0,&distnetworkdm);CHKERRQ(ierr); ierr = DMDestroy(&networkdm);CHKERRQ(ierr); networkdm = distnetworkdm; } PetscLogStagePop(); ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr); ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr); #if 0 PetscInt numComponents; EDGEDATA edge; PetscInt offset,key,kk; DMNetworkComponentGenericDataType *arr; VERTEXDATA bus; GEN gen; LOAD load; for (i = eStart; i < eEnd; i++) { ierr = DMNetworkGetComponentDataArray(networkdm,&arr);CHKERRQ(ierr); ierr = DMNetworkGetComponentTypeOffset(networkdm,i,0,&key,&offset);CHKERRQ(ierr); edge = (EDGEDATA)(arr+offset); ierr = DMNetworkGetNumComponents(networkdm,i,&numComponents);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d ncomps = %d Line %d ---- %d\n",crank,numComponents,edge->internal_i,edge->internal_j);CHKERRQ(ierr); } for (i = vStart; i < vEnd; i++) { ierr = DMNetworkGetComponentDataArray(networkdm,&arr);CHKERRQ(ierr); ierr = DMNetworkGetNumComponents(networkdm,i,&numComponents);CHKERRQ(ierr); for (kk=0; kk < numComponents; kk++) { ierr = DMNetworkGetComponentTypeOffset(networkdm,i,kk,&key,&offset);CHKERRQ(ierr); if (key == 1) { bus = (VERTEXDATA)(arr+offset); ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d ncomps = %d Bus %d\n",crank,numComponents,bus->internal_i);CHKERRQ(ierr); } else if (key == 2) { gen = (GEN)(arr+offset); ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d Gen pg = %f qg = %f\n",crank,gen->pg,gen->qg);CHKERRQ(ierr); } else if (key == 3) { load = (LOAD)(arr+offset); ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d Load pl = %f ql = %f\n",crank,load->pl,load->ql);CHKERRQ(ierr); } } } #endif /* Broadcast Sbase to all processors */ ierr = MPI_Bcast(&User.Sbase,1,MPIU_SCALAR,0,PETSC_COMM_WORLD);CHKERRQ(ierr); ierr = DMCreateGlobalVector(networkdm,&X);CHKERRQ(ierr); ierr = VecDuplicate(X,&F);CHKERRQ(ierr); ierr = DMCreateMatrix(networkdm,&J);CHKERRQ(ierr); ierr = MatSetOption(J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = SetInitialValues(networkdm,X,&User);CHKERRQ(ierr); /* HOOK UP SOLVER */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,networkdm);CHKERRQ(ierr); ierr = SNESSetFunction(snes,F,FormFunction,&User);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,FormJacobian,&User);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,X);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&networkdm);CHKERRQ(ierr); } ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { SNES snes; /* nonlinear solver context */ KSP ksp; /* linear solver context */ PC pc; /* preconditioner context */ Vec x,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscErrorCode ierr; PetscInt its; PetscMPIInt size,rank; PetscScalar pfive = .5,*xx; PetscBool flg; AppCtx user; /* user-defined work context */ IS isglobal,islocal; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);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);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); if (size > 1){ ierr = VecCreateSeq(PETSC_COMM_SELF,2,&user.xloc);CHKERRQ(ierr); ierr = VecDuplicate(user.xloc,&user.rloc);CHKERRQ(ierr); /* Create the scatter between the global x and local xloc */ ierr = ISCreateStride(MPI_COMM_SELF,2,0,1,&islocal);CHKERRQ(ierr); ierr = ISCreateStride(MPI_COMM_SELF,2,0,1,&isglobal);CHKERRQ(ierr); ierr = VecScatterCreate(x,isglobal,user.xloc,islocal,&user.scatter);CHKERRQ(ierr); ierr = ISDestroy(&isglobal);CHKERRQ(ierr); ierr = ISDestroy(&islocal);CHKERRQ(ierr); } /* Create Jacobian matrix data structure */ ierr = MatCreate(PETSC_COMM_WORLD,&J);CHKERRQ(ierr); ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,2,2);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = MatSetUp(J);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-hard",&flg);CHKERRQ(ierr); if (!flg) { /* Set function evaluation routine and vector. */ ierr = SNESSetFunction(snes,r,FormFunction1,&user);CHKERRQ(ierr); /* Set Jacobian matrix data structure and Jacobian evaluation routine */ ierr = SNESSetJacobian(snes,J,J,FormJacobian1,PETSC_NULL);CHKERRQ(ierr); } else { if (size != 1) SETERRQ(PETSC_COMM_SELF,1,"This case is a uniprocessor example only!"); ierr = SNESSetFunction(snes,r,FormFunction2,PETSC_NULL);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,FormJacobian2,PETSC_NULL);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Set linear solver defaults for this problem. By extracting the KSP, KSP, and PC contexts from the SNES context, we can then directly call any KSP, KSP, and PC routines to set various options. */ ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,1.e-4,PETSC_DEFAULT,PETSC_DEFAULT,20);CHKERRQ(ierr); /* Set SNES/KSP/KSP/PC runtime options, e.g., -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc> These options will override those specified above as long as SNESSetFromOptions() is called _after_ any other customization routines. */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Evaluate initial guess; then solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (!flg) { ierr = VecSet(x,pfive);CHKERRQ(ierr); } else { ierr = VecGetArray(x,&xx);CHKERRQ(ierr); xx[0] = 2.0; xx[1] = 3.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 = SNESSolve(snes,PETSC_NULL,x);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); if (flg) { Vec f; ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = SNESGetFunction(snes,&f,0,0);CHKERRQ(ierr); ierr = VecView(r,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = PetscPrintf(PETSC_COMM_WORLD,"number of SNES iterations = %D\n",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 = MatDestroy(&J);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); if (size > 1){ ierr = VecDestroy(&user.xloc);CHKERRQ(ierr); ierr = VecDestroy(&user.rloc);CHKERRQ(ierr); ierr = VecScatterDestroy(&user.scatter);CHKERRQ(ierr); } ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { SNES snes; /* SNES context */ Mat J; /* Jacobian matrix */ DM da; Vec x,r; /* vectors */ PetscErrorCode ierr; PetscInt N = 5; MatNullSpace constants; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-n",&N,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create vector data structures; set function evaluation routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create distributed array (DMDA) to manage parallel grid and vectors */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,N,1,1,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); /* Extract global and local 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); /* Set function evaluation routine and vector. Whenever the nonlinear solver needs to compute the nonlinear function, it will call this routine. - Note that the final routine argument is the user-defined context that provides application-specific data for the function evaluation routine. */ ierr = SNESSetFunction(snes,r,FormFunction,da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix data structure; set Jacobian evaluation routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = MatNullSpaceCreate(PETSC_COMM_WORLD,PETSC_TRUE,0,NULL,&constants);CHKERRQ(ierr); ierr = MatSetNullSpace(J,constants);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,FormJacobian,da);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,x);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&constants);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/* FormFunction - Evaluates the function and corresponding gradient. Input Parameters: tao - the Tao context X - the input vector ptr - optional user-defined context, as set by TaoSetObjectiveAndGradientRoutine() Output Parameters: f - the newly evaluated function */ PetscErrorCode FormFunction(Tao tao,Vec P,PetscReal *f,void *ctx0) { TS ts; SNES snes_alg; PetscErrorCode ierr; Userctx *ctx = (Userctx*)ctx0; Vec X; Mat J; /* sensitivity context */ PetscScalar *x_ptr; PetscViewer Xview,Ybusview; Vec F_alg; Vec Xdot; PetscInt row_loc,col_loc; PetscScalar val; ierr = VecGetArray(P,&x_ptr);CHKERRQ(ierr); PG[0] = x_ptr[0]; PG[1] = x_ptr[1]; PG[2] = x_ptr[2]; ierr = VecRestoreArray(P,&x_ptr);CHKERRQ(ierr); ctx->stepnum = 0; ierr = VecZeroEntries(ctx->vec_q);CHKERRQ(ierr); /* Read initial voltage vector and Ybus */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"X.bin",FILE_MODE_READ,&Xview);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"Ybus.bin",FILE_MODE_READ,&Ybusview);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&ctx->V0);CHKERRQ(ierr); ierr = VecSetSizes(ctx->V0,PETSC_DECIDE,ctx->neqs_net);CHKERRQ(ierr); ierr = VecLoad(ctx->V0,Xview);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&ctx->Ybus);CHKERRQ(ierr); ierr = MatSetSizes(ctx->Ybus,PETSC_DECIDE,PETSC_DECIDE,ctx->neqs_net,ctx->neqs_net);CHKERRQ(ierr); ierr = MatSetType(ctx->Ybus,MATBAIJ);CHKERRQ(ierr); /* ierr = MatSetBlockSize(ctx->Ybus,2);CHKERRQ(ierr); */ ierr = MatLoad(ctx->Ybus,Ybusview);CHKERRQ(ierr); ierr = PetscViewerDestroy(&Xview);CHKERRQ(ierr); ierr = PetscViewerDestroy(&Ybusview);CHKERRQ(ierr); ierr = DMCreateGlobalVector(ctx->dmpgrid,&X);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&J);CHKERRQ(ierr); ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,ctx->neqs_pgrid,ctx->neqs_pgrid);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = PreallocateJacobian(J,ctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,(TSIFunction) IFunction,ctx);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,(TSIJacobian)IJacobian,ctx);CHKERRQ(ierr); ierr = TSSetApplicationContext(ts,ctx);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MonitorUpdateQ,ctx,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SetInitialGuess(X,ctx);CHKERRQ(ierr); ierr = VecDuplicate(X,&F_alg);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes_alg);CHKERRQ(ierr); ierr = SNESSetFunction(snes_alg,F_alg,AlgFunction,ctx);CHKERRQ(ierr); ierr = MatZeroEntries(J);CHKERRQ(ierr); ierr = SNESSetJacobian(snes_alg,J,J,AlgJacobian,ctx);CHKERRQ(ierr); ierr = SNESSetOptionsPrefix(snes_alg,"alg_");CHKERRQ(ierr); ierr = SNESSetFromOptions(snes_alg);CHKERRQ(ierr); ctx->alg_flg = PETSC_TRUE; /* Solve the algebraic equations */ ierr = SNESSolve(snes_alg,NULL,X);CHKERRQ(ierr); /* Just to set up the Jacobian structure */ ierr = VecDuplicate(X,&Xdot);CHKERRQ(ierr); ierr = IJacobian(ts,0.0,X,Xdot,0.0,J,J,ctx);CHKERRQ(ierr); ierr = VecDestroy(&Xdot);CHKERRQ(ierr); ctx->stepnum++; ierr = TSSetDuration(ts,1000,ctx->tfaulton);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.01);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* ierr = TSSetPostStep(ts,SaveSolution);CHKERRQ(ierr); */ ctx->alg_flg = PETSC_FALSE; /* Prefault period */ ierr = TSSolve(ts,X);CHKERRQ(ierr); /* Create the nonlinear solver for solving the algebraic system */ /* Note that although the algebraic system needs to be solved only for Idq and V, we reuse the entire system including xgen. The xgen variables are held constant by setting their residuals to 0 and putting a 1 on the Jacobian diagonal for xgen rows */ ierr = MatZeroEntries(J);CHKERRQ(ierr); /* Apply disturbance - resistive fault at ctx->faultbus */ /* This is done by adding shunt conductance to the diagonal location in the Ybus matrix */ row_loc = 2*ctx->faultbus; col_loc = 2*ctx->faultbus+1; /* Location for G */ val = 1/ctx->Rfault; ierr = MatSetValues(ctx->Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); row_loc = 2*ctx->faultbus+1; col_loc = 2*ctx->faultbus; /* Location for G */ val = 1/ctx->Rfault; ierr = MatSetValues(ctx->Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(ctx->Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(ctx->Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ctx->alg_flg = PETSC_TRUE; /* Solve the algebraic equations */ ierr = SNESSolve(snes_alg,NULL,X);CHKERRQ(ierr); ctx->stepnum++; /* Disturbance period */ ierr = TSSetDuration(ts,1000,ctx->tfaultoff);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,ctx->tfaulton,.01);CHKERRQ(ierr); ctx->alg_flg = PETSC_FALSE; ierr = TSSolve(ts,X);CHKERRQ(ierr); /* Remove the fault */ row_loc = 2*ctx->faultbus; col_loc = 2*ctx->faultbus+1; val = -1/ctx->Rfault; ierr = MatSetValues(ctx->Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); row_loc = 2*ctx->faultbus+1; col_loc = 2*ctx->faultbus; val = -1/ctx->Rfault; ierr = MatSetValues(ctx->Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(ctx->Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(ctx->Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatZeroEntries(J);CHKERRQ(ierr); ctx->alg_flg = PETSC_TRUE; /* Solve the algebraic equations */ ierr = SNESSolve(snes_alg,NULL,X);CHKERRQ(ierr); ctx->stepnum++; /* Post-disturbance period */ ierr = TSSetDuration(ts,1000,ctx->tmax);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,ctx->tfaultoff,.01);CHKERRQ(ierr); ctx->alg_flg = PETSC_TRUE; ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = VecGetArray(ctx->vec_q,&x_ptr);CHKERRQ(ierr); *f = x_ptr[0]; ierr = VecRestoreArray(ctx->vec_q,&x_ptr);CHKERRQ(ierr); ierr = MatDestroy(&ctx->Ybus);CHKERRQ(ierr); ierr = VecDestroy(&ctx->V0);CHKERRQ(ierr); ierr = SNESDestroy(&snes_alg);CHKERRQ(ierr); ierr = VecDestroy(&F_alg);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; /* nonlinear solver */ Vec Hu,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ AppCtx user; /* user-defined work context */ PetscInt its, i, tmpxs, tmpxm; /* iteration count, index, etc. */ PetscReal tmp1, tmp2, tmp3, tmp4, tmp5, errnorms[2], descaleNode[2]; PetscTruth eps_set = PETSC_FALSE, dump = PETSC_FALSE, exactinitial = PETSC_FALSE, snes_mf_set, snes_fd_set; MatFDColoring matfdcoloring = 0; ISColoring iscoloring; SNESConvergedReason reason; /* Check convergence */ PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &user.rank); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "BODVARDSSON solves for thickness and velocity in 1D, steady ice stream\n" " [run with -help for info and options]\n");CHKERRQ(ierr); user.n = 3.0; /* Glen flow law exponent */ user.secpera = 31556926.0; user.rho = 910.0; /* kg m^-3 */ user.rhow = 1028.0; /* kg m^-3 */ user.g = 9.81; /* m s^-2 */ /* ask Test N for its parameters, but only those we need to solve */ ierr = params_exactN(&(user.H0), &tmp1, &(user.xc), &tmp2, &tmp3, &tmp4, &tmp5, &(user.Txc)); CHKERRQ(ierr); /* regularize using strain rate of 1/xc per year */ user.epsilon = (1.0 / user.secpera) / user.xc; /* tools for non-dimensionalizing to improve equation scaling */ user.scaleNode[0] = 1000.0; user.scaleNode[1] = 100.0 / user.secpera; ierr = PetscOptionsTruth("-snes_mf","","",PETSC_FALSE,&snes_mf_set,NULL);CHKERRQ(ierr); ierr = PetscOptionsTruth("-snes_fd","","",PETSC_FALSE,&snes_fd_set,NULL);CHKERRQ(ierr); if (!snes_mf_set && !snes_fd_set) { PetscPrintf(PETSC_COMM_WORLD, "\n***ERROR: bodvardsson needs one or zero of '-snes_mf', '-snes_fd'***\n\n" "USAGE FOLLOWS ...\n\n%s",help); PetscEnd(); } if (snes_fd_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " using approximate Jacobian; finite-differencing using coloring\n"); CHKERRQ(ierr); } else if (snes_mf_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " matrix free; no preconditioner\n"); CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, " true Jacobian\n"); CHKERRQ(ierr); } ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL, "bodvardsson program options",__FILE__);CHKERRQ(ierr); { ierr = PetscOptionsTruth("-bod_up_one","","",PETSC_FALSE,&user.upwind1,NULL);CHKERRQ(ierr); ierr = PetscOptionsTruth("-bod_exact_init","","",PETSC_FALSE,&exactinitial,NULL);CHKERRQ(ierr); ierr = PetscOptionsTruth("-bod_dump", "dump out exact and approximate solution and residual, as asci","", dump,&dump,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-bod_epsilon","regularization (a strain rate in units of 1/a)","", user.epsilon * user.secpera,&user.epsilon,&eps_set);CHKERRQ(ierr); if (eps_set) user.epsilon *= 1.0 / user.secpera; } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Create machinery for parallel grid management (DA), nonlinear solver (SNES), and Vecs for fields (solution, RHS). Note default Mx=46 grid points means dx=10 km. Also degrees of freedom = 2 (thickness and velocity at each point) and stencil radius = ghost width = 2 for 2nd-order upwinding. */ user.solnghostwidth = 2; ierr = DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,-46,2,user.solnghostwidth,PETSC_NULL,&user.da); CHKERRQ(ierr); ierr = DASetUniformCoordinates(user.da,0.0,user.xc, PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DASetFieldName(user.da,0,"ice thickness [non-dimensional]"); CHKERRQ(ierr); ierr = DASetFieldName(user.da,1,"ice velocity [non-dimensional]"); CHKERRQ(ierr); ierr = DAGetInfo(user.da,PETSC_IGNORE,&user.Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); ierr = DAGetCorners(user.da,&user.xs,PETSC_NULL,PETSC_NULL,&user.xm,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); user.dx = user.xc / (PetscReal)(user.Mx-1); /* another DA for scalar parameters, with same length */ ierr = DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,user.Mx,1,1,PETSC_NULL,&user.scalarda);CHKERRQ(ierr); ierr = DASetUniformCoordinates(user.scalarda,0.0,user.xc, PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); /* check that parallel layout of scalar DA is same as dof=2 DA */ ierr = DAGetCorners(user.scalarda,&tmpxs,PETSC_NULL,PETSC_NULL,&tmpxm,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); if ((tmpxs != user.xs) || (tmpxm != user.xm)) { PetscPrintf(PETSC_COMM_SELF, "\n***ERROR: rank %d gets different ownership range for the two DAs! ENDING ...***\n\n", user.rank); PetscEnd(); } ierr = PetscPrintf(PETSC_COMM_WORLD, " Mx = %D points, dx = %.3f m\n H0 = %.2f m, xc = %.2f km, Txc = %.5e Pa m\n", user.Mx, user.dx, user.H0, user.xc/1000.0, user.Txc);CHKERRQ(ierr); /* Extract/allocate global vectors from DAs and duplicate for remaining same types */ ierr = DACreateGlobalVector(user.da,&Hu);CHKERRQ(ierr); ierr = VecSetBlockSize(Hu,2);CHKERRQ(ierr); ierr = VecDuplicate(Hu,&r);CHKERRQ(ierr); /* inherits block size */ ierr = VecDuplicate(Hu,&user.Huexact);CHKERRQ(ierr); /* ditto */ ierr = DACreateGlobalVector(user.scalarda,&user.M);CHKERRQ(ierr); ierr = VecDuplicate(user.M,&user.Bstag);CHKERRQ(ierr); ierr = VecDuplicate(user.M,&user.beta);CHKERRQ(ierr); ierr = DASetLocalFunction(user.da,(DALocalFunction1)scshell);CHKERRQ(ierr); ierr = DASetLocalJacobian(user.da,(DALocalFunction1)BodJacobianMatrixLocal);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetFunction(snes,r,SNESDAFormFunction,&user);CHKERRQ(ierr); /* setting up a matrix is only actually needed for -snes_fd case */ ierr = DAGetMatrix(user.da,MATAIJ,&J);CHKERRQ(ierr); if (snes_fd_set) { /* tools needed so DA can use sparse matrix for its F.D. Jacobian approx */ ierr = DAGetColoring(user.da,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode (*)(void))SNESDAFormFunction,&user);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESDefaultComputeJacobianColor,matfdcoloring);CHKERRQ(ierr); } else { ierr = SNESSetJacobian(snes,J,J,SNESDAComputeJacobian,&user);CHKERRQ(ierr); } ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* the the Bodvardsson (1955) exact solution allows setting M(x), B(x), beta(x), T(xc) */ ierr = FillDistributedParams(&user);CHKERRQ(ierr); /* the exact thickness and exact ice velocity (user.uHexact) are known from Bodvardsson (1955) */ ierr = FillExactSoln(&user); CHKERRQ(ierr); if (exactinitial) { ierr = PetscPrintf(PETSC_COMM_WORLD," using exact solution as initial guess\n"); CHKERRQ(ierr); /* the initial guess is the exact continuum solution */ ierr = VecCopy(user.Huexact,Hu); CHKERRQ(ierr); } else { ierr = FillInitial(&user, &Hu); CHKERRQ(ierr); } /************ SOLVE NONLINEAR SYSTEM ************/ /* recall that RHS r is used internally by KSP, and is set by the SNES */ for (i = 0; i < 2; i++) descaleNode[i] = 1.0 / user.scaleNode[i]; ierr = VecStrideScaleAll(Hu,descaleNode); CHKERRQ(ierr); /* de-dimensionalize initial guess */ ierr = SNESSolve(snes,PETSC_NULL,Hu);CHKERRQ(ierr); ierr = VecStrideScaleAll(Hu,user.scaleNode); CHKERRQ(ierr); /* put back in "real" scale */ ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " %s Number of Newton iterations = %D\n", SNESConvergedReasons[reason],its);CHKERRQ(ierr); if (dump) { ierr = PetscPrintf(PETSC_COMM_WORLD, " viewing combined result Hu\n");CHKERRQ(ierr); ierr = VecView(Hu,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " viewing combined exact result Huexact\n");CHKERRQ(ierr); ierr = VecView(user.Huexact,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " viewing final combined residual at Hu\n");CHKERRQ(ierr); ierr = VecView(r,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } /* evaluate error relative to exact solution */ ierr = VecAXPY(Hu,-1.0,user.Huexact); CHKERRQ(ierr); /* Hu = - Huexact + Hu */ ierr = VecStrideNormAll(Hu,NORM_INFINITY,errnorms); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "(dx,errHinf,erruinf) %.3f %.4e %.4e\n", user.dx,errnorms[0],errnorms[1]*user.secpera);CHKERRQ(ierr); ierr = VecDestroy(Hu);CHKERRQ(ierr); ierr = VecDestroy(r);CHKERRQ(ierr); ierr = VecDestroy(user.Huexact);CHKERRQ(ierr); ierr = VecDestroy(user.M);CHKERRQ(ierr); ierr = VecDestroy(user.Bstag);CHKERRQ(ierr); ierr = VecDestroy(user.beta);CHKERRQ(ierr); ierr = MatDestroy(J); CHKERRQ(ierr); ierr = SNESDestroy(snes);CHKERRQ(ierr); ierr = DADestroy(user.da);CHKERRQ(ierr); ierr = DADestroy(user.scalarda);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc, char **argv) { MPI_Comm comm; SNES snes; /* nonlinear solver */ Vec u,r,b; /* solution, residual, and rhs vectors */ Mat A,J; /* Jacobian matrix */ PetscInt problem = 1, N = 10; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help); if (ierr) return ierr; comm = PETSC_COMM_WORLD; ierr = PetscOptionsGetInt(NULL,NULL, "-problem", &problem, NULL); CHKERRQ(ierr); ierr = VecCreate(comm, &u); CHKERRQ(ierr); ierr = VecSetSizes(u, PETSC_DETERMINE, N); CHKERRQ(ierr); ierr = VecSetFromOptions(u); CHKERRQ(ierr); ierr = VecDuplicate(u, &r); CHKERRQ(ierr); ierr = VecDuplicate(u, &b); CHKERRQ(ierr); ierr = MatCreate(comm, &A); CHKERRQ(ierr); ierr = MatSetSizes(A, PETSC_DETERMINE, PETSC_DETERMINE, N, N); CHKERRQ(ierr); ierr = MatSetFromOptions(A); CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(A, 5, NULL); CHKERRQ(ierr); J = A; switch (problem) { case 1: ierr = ConstructProblem1(A, b); CHKERRQ(ierr); break; case 2: ierr = ConstructProblem2(A, b); CHKERRQ(ierr); break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid problem number %d", problem); } ierr = SNESCreate(PETSC_COMM_WORLD, &snes); CHKERRQ(ierr); ierr = SNESSetJacobian(snes, A, J, ComputeJacobianLinear, NULL); CHKERRQ(ierr); ierr = SNESSetFunction(snes, r, ComputeFunctionLinear, A); CHKERRQ(ierr); ierr = SNESSetFromOptions(snes); CHKERRQ(ierr); ierr = SNESSolve(snes, b, u); CHKERRQ(ierr); ierr = VecView(u, NULL); CHKERRQ(ierr); switch (problem) { case 1: ierr = CheckProblem1(A, b, u); CHKERRQ(ierr); break; case 2: ierr = CheckProblem2(A, b, u); CHKERRQ(ierr); break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid problem number %d", problem); } if (A != J) { ierr = MatDestroy(&A); CHKERRQ(ierr); } ierr = MatDestroy(&J); CHKERRQ(ierr); ierr = VecDestroy(&u); CHKERRQ(ierr); ierr = VecDestroy(&r); CHKERRQ(ierr); ierr = VecDestroy(&b); CHKERRQ(ierr); ierr = SNESDestroy(&snes); CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc, char **argv) { MPI_Comm comm; PetscMPIInt rank; PetscErrorCode ierr; User user; PetscLogDouble v1, v2; PetscInt nplot = 0; char fileName[2048]; ierr = PetscInitialize(&argc, &argv, (char*) 0, help);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); ierr = PetscNew(&user->algebra);CHKERRQ(ierr); ierr = PetscNew(&user->model);CHKERRQ(ierr); ierr = PetscNew(&user->model->physics);CHKERRQ(ierr); Algebra algebra = user->algebra; ierr = LoadOptions(comm, user);CHKERRQ(ierr); ierr = PetscTime(&v1);CHKERRQ(ierr); ierr = CreateMesh(comm, user);CHKERRQ(ierr); ierr = PetscTime(&v2);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Read and Distribute mesh takes %f sec \n", v2 - v1);CHKERRQ(ierr); ierr = SetUpLocalSpace(user);CHKERRQ(ierr); //Set up the dofs of each element ierr = ConstructGeometryFVM(&user->facegeom, &user->cellgeom, user);CHKERRQ(ierr); ierr = LimiterSetup(user);CHKERRQ(ierr); if (user->TimeIntegralMethod == EXPLICITMETHOD) { // explicit method if(user->myownexplicitmethod){// Using the fully explicit method based on my own routing ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on my own routing\n");CHKERRQ(ierr); user->current_time = user->initial_time; user->current_step = 1; ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = VecSet(algebra->solution, 0);CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); if(1){ PetscViewer viewer; ierr = OutputVTK(user->dm, "intialcondition.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing the initial condition intialcondition.vtk!!! \n");CHKERRQ(ierr); } ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr); if(user->Explicit_RK2||user->Explicit_RK4){ ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the second order Runge Kutta method \n");CHKERRQ(ierr); }else{ ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the first order forward Euler method \n");CHKERRQ(ierr); } nplot = 0; //the plot step while(user->current_time < (user->final_time - 0.05 * user->dt)){ user->current_time = user->current_time + user->dt; ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); if(0){ PetscViewer viewer; ierr = OutputVTK(user->dm, "function.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->fn, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } if(user->Explicit_RK2){ /* U^n_1 = U^n + 0.5*dt*f(U^n) U^{n+1} = U^n + dt*f(U^n_1) */ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); //note that algebra->oldsolution and algebra->solution are both U^n ierr = VecAXPY(algebra->solution, 0.5*user->dt, algebra->fn);CHKERRQ(ierr); //U^n_1 = U^n + 0.5*dt*f(U^n), now algebra->solution is U^n_1, and algebra->fn is f(U^n) ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); //algebra->fn is f(U^n_1) // reset the algebra->solution to U^n ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr); // now algebra->solution is U^{n+1} = U^n + dt*f(U^n_1) }else if(user->Explicit_RK4){ /* refer to https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods k_1 = f(U^n) U^n_1 = U^n + 0.5*dt*k_1 k_2 = f(U^n_1) U^n_2 = U^n + 0.5*dt*k_2 k_3 = f(U^n_2) U^n_3 = U^n + 0.5*dt*k_3 k_4 = f(U^n_3) U^{n+1} = U^n + dt/6*(k_1 + 2*k_2 + 2*k_3 + k_4) */ Vec VecTemp; // store the U^n_1 Vec k1, k2, k3, k4; ierr = VecDuplicate(algebra->solution, &k1);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &k2);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &k3);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &k4);CHKERRQ(ierr); ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); ierr = VecCopy(algebra->fn, k1);CHKERRQ(ierr); //note that algebra->oldsolution and algebra->solution are both U^n ierr = VecAXPY(algebra->solution, 0.5*user->dt, k1);CHKERRQ(ierr); //U^n_1 = U^n + 0.5*dt*k1, now algebra->solution is U^n_1, and algebra->fn is f(U^n) ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); //algebra->fn is f(U^n_1) ierr = VecCopy(algebra->fn, k2);CHKERRQ(ierr); // reset the algebra->solution to U^n ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, 0.5*user->dt, k2);CHKERRQ(ierr); //U^n_2 = U^n + 0.5*dt*k2, now algebra->solution is U^n_2, and algebra->fn is f(U^n_1) ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); //algebra->fn is f(U^n_2) ierr = VecCopy(algebra->fn, k3);CHKERRQ(ierr); // reset the algebra->solution to U^n ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, 0.5*user->dt, k3);CHKERRQ(ierr); //U^n_3 = U^n + 0.5*dt*k3, now algebra->solution is U^n_3, and algebra->fn is f(U^n_2) ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); //algebra->fn is f(U^n_3) ierr = VecCopy(algebra->fn, k4);CHKERRQ(ierr); //U^{n+1} = U^n + dt/6*(k_1 + 2*k_2 + 2*k_3 + k_4) PetscReal temp; temp = user->dt/6; // reset the algebra->solution to U^n ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, temp, k1);CHKERRQ(ierr); // now algebra->solution is U^n + dt/6*k_1 ierr = VecAXPY(algebra->solution, 2*temp, k2);CHKERRQ(ierr); // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2 ierr = VecAXPY(algebra->solution, 2*temp, k3);CHKERRQ(ierr); // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2 + 2*dt/6*k_3 ierr = VecAXPY(algebra->solution, temp, k4);CHKERRQ(ierr); // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2 + 2*dt/6*k_3 + dt/6*k_4 ierr = VecDestroy(&k1);CHKERRQ(ierr); ierr = VecDestroy(&k2);CHKERRQ(ierr); ierr = VecDestroy(&k3);CHKERRQ(ierr); ierr = VecDestroy(&k4);CHKERRQ(ierr); }else{ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr); } {// Monitor the solution and function norms PetscReal norm; PetscLogDouble space =0; PetscInt size; PetscReal fnnorm; ierr = VecNorm(algebra->fn,NORM_2,&fnnorm);CHKERRQ(ierr); //ierr = VecView(algebra->fn, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecNorm(algebra->solution,NORM_2,&norm);CHKERRQ(ierr); ierr = VecGetSize(algebra->solution, &size);CHKERRQ(ierr); norm = norm/size; fnnorm = fnnorm/size; if (norm>1.e5) { SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_LIB, "The norm of the solution is: %f (current time: %f). The explicit method is going to DIVERGE!!!", norm, user->current_time); } if (user->current_step%10==0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with solution norm = %g and founction norm = %g \n", user->current_step, user->current_time, norm, fnnorm);CHKERRQ(ierr); } // ierr = PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr); // if (user->current_step%10==0) { // ierr = PetscPrintf(PETSC_COMM_WORLD,"Current space PetscMalloc()ed %g M\n", // space/(1024*1024));CHKERRQ(ierr); // } } { // Monitor the difference of two steps' solution PetscReal norm; ierr = VecAXPY(algebra->oldsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->oldsolution,NORM_2,&norm);CHKERRQ(ierr); if (user->current_step%10==0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with ||u_k-u_{k-1}|| = %g \n", user->current_step, user->current_time, norm);CHKERRQ(ierr); } if((norm<1.e-6)||(user->current_step > user->max_time_its)){ if(norm<1.e-6) ierr = PetscPrintf(PETSC_COMM_WORLD,"\n Convergence with ||u_k-u_{k-1}|| = %g < 1.e-6\n\n", norm);CHKERRQ(ierr); if(user->current_step > user->max_time_its) ierr = PetscPrintf(PETSC_COMM_WORLD,"\n Convergence with reaching the max time its\n\n");CHKERRQ(ierr); break; } } // output the solution if (user->output_solution && (user->current_step%user->steps_output==0)){ PetscViewer viewer; Vec solution_unscaled; // Note the the algebra->solution is scaled by the density, so this is for the unscaled solution nplot = user->current_step/user->steps_output; // update file name for the current time step ierr = VecDuplicate(algebra->solution, &solution_unscaled);CHKERRQ(ierr); ierr = ReformatSolution(algebra->solution, solution_unscaled, user);CHKERRQ(ierr); ierr = PetscSNPrintf(fileName, sizeof(fileName),"%s_%d.vtk",user->solutionfile, nplot);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing solution %s (current time %f)\n", fileName, user->current_time);CHKERRQ(ierr); ierr = OutputVTK(user->dm, fileName, &viewer);CHKERRQ(ierr); ierr = VecView(solution_unscaled, viewer);CHKERRQ(ierr); ierr = VecDestroy(&solution_unscaled);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } user->current_step++; } ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr); }else{ // Using the fully explicit method based on the PETSC TS routing PetscReal ftime; TS ts; TSConvergedReason reason; PetscInt nsteps; //PetscReal minRadius; //ierr = DMPlexTSGetGeometry(user->dm, NULL, NULL, &minRadius);CHKERRQ(ierr); //user->dt = 0.9*4 * minRadius / 1.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on the PETSC TS routing\n");CHKERRQ(ierr); ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = VecSet(algebra->solution, 0.0);CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = TSCreate(comm, &ts);CHKERRQ(ierr); ierr = TSSetType(ts, TSEULER);CHKERRQ(ierr); ierr = TSSetDM(ts, user->dm);CHKERRQ(ierr); ierr = TSMonitorSet(ts,TSMonitorFunctionError,(void*)user,NULL);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts, NULL, MyRHSFunction, user);CHKERRQ(ierr); ierr = TSSetDuration(ts, 1000, user->final_time);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts, user->initial_time, user->dt);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts, algebra->solution);CHKERRQ(ierr); ierr = TSGetSolveTime(ts, &ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts, &nsteps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts, &reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],ftime,nsteps);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); } if(user->benchmark_couette) { ierr = DMCreateGlobalVector(user->dm, &algebra->exactsolution);CHKERRQ(ierr); ierr = ComputeExactSolution(user->dm, user->current_time, algebra->exactsolution, user);CHKERRQ(ierr); } if(user->benchmark_couette) { PetscViewer viewer; PetscReal norm; ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Final time at %f, Error: ||u_k-u|| = %g \n", user->current_time, norm);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr); if(user->myownexplicitmethod){ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr);} ierr = VecDestroy(&algebra->exactsolution);CHKERRQ(ierr); ierr = DMDestroy(&user->dm);CHKERRQ(ierr); } else if (user->TimeIntegralMethod == IMPLICITMETHOD) { // Using the fully implicit method ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully implicit method\n");CHKERRQ(ierr); ierr = SNESCreate(comm,&user->snes);CHKERRQ(ierr); ierr = SNESSetDM(user->snes,user->dm);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->f);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldfn);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = DMSetMatType(user->dm, MATAIJ);CHKERRQ(ierr); // ierr = DMCreateMatrix(user->dm, &algebra->A);CHKERRQ(ierr); ierr = DMCreateMatrix(user->dm, &algebra->J);CHKERRQ(ierr); if (user->JdiffP) { /*Set up the preconditioner matrix*/ ierr = DMCreateMatrix(user->dm, &algebra->P);CHKERRQ(ierr); }else{ algebra->P = algebra->J; } ierr = MatSetOption(algebra->J, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRQ(ierr); /*set nonlinear function */ ierr = SNESSetFunction(user->snes, algebra->f, FormFunction, (void*)user);CHKERRQ(ierr); /* compute Jacobian */ ierr = SNESSetJacobian(user->snes, algebra->J, algebra->P, FormJacobian, (void*)user);CHKERRQ(ierr); ierr = SNESSetFromOptions(user->snes);CHKERRQ(ierr); /* do the solve */ if (user->timestep == TIMESTEP_STEADY_STATE) { ierr = SolveSteadyState(user);CHKERRQ(ierr); } else { ierr = SolveTimeDependent(user);CHKERRQ(ierr); } if (user->output_solution){ PetscViewer viewer; Vec solution_unscaled; // Note the the algebra->solution is scaled by the density, so this is for the unscaled solution ierr = VecDuplicate(algebra->solution, &solution_unscaled);CHKERRQ(ierr); ierr = ReformatSolution(algebra->solution, solution_unscaled, user);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(solution_unscaled, viewer);CHKERRQ(ierr); ierr = VecDestroy(&solution_unscaled);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } if(user->benchmark_couette) { PetscViewer viewer; PetscReal norm; ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error: ||u_k-u|| = %g \n", norm);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->f);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldfn);CHKERRQ(ierr); ierr = SNESDestroy(&user->snes);CHKERRQ(ierr); ierr = DMDestroy(&user->dm);CHKERRQ(ierr); } else { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"WRONG option for the time integral method. Using the option '-time_integral_method 0 or 1'"); } ierr = VecDestroy(&user->cellgeom);CHKERRQ(ierr); ierr = VecDestroy(&user->facegeom);CHKERRQ(ierr); ierr = DMDestroy(&user->dmGrad);CHKERRQ(ierr); ierr = PetscFunctionListDestroy(&LimitList);CHKERRQ(ierr); ierr = PetscFree(user->model->physics);CHKERRQ(ierr); ierr = PetscFree(user->algebra);CHKERRQ(ierr); ierr = PetscFree(user->model);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); { PetscLogDouble space =0; ierr = PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Unfreed space at the End %g M\n", space/(1024*1024));CHKERRQ(ierr); } ierr = PetscFinalize(); return(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; }