int main(int argc,char **argv) { TS ts; SNES snes; SNESLineSearch linesearch; Vec x; AppCtx ctx; PetscErrorCode ierr; DM da; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = SetFromOptions(&ctx);CHKERRQ(ierr); ierr = TSCreate(PETSC_COMM_WORLD, &ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetIFunction(ts, NULL, FormIFunction, &ctx);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,N_SPECIES,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"species A");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"species B");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"species C");CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&ctx);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = FormInitialGuess(da, &ctx, x);CHKERRQ(ierr); ierr = TSSetDM(ts, da);CHKERRQ(ierr); ierr = TSSetDuration(ts,10000,1000.0);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,1.0);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); ierr = SNESLineSearchSetPostCheck(linesearch, ReactingFlowPostCheck, (void*)&ctx);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; Vec x,c; PetscErrorCode ierr; DM da; PetscInitialize(&argc,&argv,(char *)0,help); ierr = TSCreate(PETSC_COMM_WORLD, &ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,1,1,PETSC_NULL,PETSC_NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"Heat");CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = FormInitialGuess(da,PETSC_NULL,x);CHKERRQ(ierr); ierr = DMDATSSetIFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,PetscReal,void*,void*,void*,void*))FormIFunctionLocal,PETSC_NULL);CHKERRQ(ierr); /* set up the coefficient */ ierr = DMGetNamedGlobalVector(da,"coefficient",&c);CHKERRQ(ierr); ierr = FormDiffusionCoefficient(da,PETSC_NULL,c);CHKERRQ(ierr); ierr = DMRestoreNamedGlobalVector(da,"coefficient",&c);CHKERRQ(ierr); ierr = DMCoarsenHookAdd(da,PETSC_NULL,CoefficientRestrictHook,ts);CHKERRQ(ierr); ierr = DMSubDomainHookAdd(da,PETSC_NULL,CoefficientSubDomainRestrictHook,ts);CHKERRQ(ierr); ierr = TSSetDM(ts, da);CHKERRQ(ierr); ierr = TSSetDuration(ts,10000,1000.0);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.05);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { AppCtx user; /* user-defined work context */ PetscInt mx,my; PetscErrorCode ierr; MPI_Comm comm; DM da; Vec x; Mat J = NULL,Jmf = NULL; MatShellCtx matshellctx; PetscInt mlocal,nlocal; PC pc; KSP ksp; PetscBool errorinmatmult = PETSC_FALSE,errorinpcapply = PETSC_FALSE,errorinpcsetup = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return(1); PetscFunctionBeginUser; ierr = PetscOptionsGetBool(NULL,"-error_in_matmult",&errorinmatmult,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_pcapply",&errorinpcapply,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_pcsetup",&errorinpcsetup,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_domain",&user.errorindomain,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_domainmf",&user.errorindomainmf,NULL);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = SNESCreate(comm,&user.snes);CHKERRQ(ierr); /* Create distributed array object to manage parallel grid and vectors for principal unknowns (x) and governing residuals (f) */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,4,1,0,0,&da);CHKERRQ(ierr); ierr = SNESSetDM(user.snes,da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&mx,&my,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); /* Problem parameters (velocity of lid, prandtl, and grashof numbers) */ user.lidvelocity = 1.0/(mx*my); user.prandtl = 1.0; user.grashof = 1.0; ierr = PetscOptionsGetReal(NULL,"-lidvelocity",&user.lidvelocity,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-prandtl",&user.prandtl,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-grashof",&user.grashof,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-contours",&user.draw_contours);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"x_velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"y_velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"Omega");CHKERRQ(ierr); ierr = DMDASetFieldName(da,3,"temperature");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create user context, set problem data, create vector data structures. Also, compute the initial guess. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); if (errorinmatmult) { ierr = MatCreateSNESMF(user.snes,&Jmf);CHKERRQ(ierr); ierr = MatSetFromOptions(Jmf);CHKERRQ(ierr); ierr = MatGetLocalSize(Jmf,&mlocal,&nlocal);CHKERRQ(ierr); matshellctx.Jmf = Jmf; ierr = MatCreateShell(PetscObjectComm((PetscObject)Jmf),mlocal,nlocal,PETSC_DECIDE,PETSC_DECIDE,&matshellctx,&J);CHKERRQ(ierr); ierr = MatShellSetOperation(J,MATOP_MULT,(void (*)(void))MatMult_MyShell);CHKERRQ(ierr); ierr = MatShellSetOperation(J,MATOP_ASSEMBLY_END,(void (*)(void))MatAssemblyEnd_MyShell);CHKERRQ(ierr); ierr = SNESSetJacobian(user.snes,J,J,MatMFFDComputeJacobian,NULL);CHKERRQ(ierr); } ierr = SNESSetFromOptions(user.snes);CHKERRQ(ierr); ierr = PetscPrintf(comm,"lid velocity = %g, prandtl # = %g, grashof # = %g\n",(double)user.lidvelocity,(double)user.prandtl,(double)user.grashof);CHKERRQ(ierr); if (errorinpcapply) { ierr = SNESGetKSP(user.snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCSHELL);CHKERRQ(ierr); ierr = PCShellSetApply(pc,PCApply_MyShell);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = FormInitialGuess(&user,da,x);CHKERRQ(ierr); if (errorinpcsetup) { ierr = SNESSetUp(user.snes);CHKERRQ(ierr); ierr = SNESSetJacobian(user.snes,NULL,NULL,SNESComputeJacobian_MyShell,NULL);CHKERRQ(ierr); } ierr = SNESSolve(user.snes,NULL,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = MatDestroy(&Jmf);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESDestroy(&user.snes);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; }
int main(int argc,char **argv) { TS ts; /* timestepping context */ Vec x,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ AppCtx user; /* user-defined work context */ PetscInt its,N; /* iterations for convergence */ PetscErrorCode ierr; PetscReal param_max = 6.81,param_min = 0.,dt; PetscReal ftime; PetscMPIInt size; PetscInitialize(&argc,&argv,NULL,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This is a uniprocessor example only"); user.mx = 4; user.my = 4; user.param = 6.0; /* Allow user to set the grid dimensions and nonlinearity parameter at run-time */ PetscOptionsGetInt(NULL,"-mx",&user.mx,NULL); PetscOptionsGetInt(NULL,"-my",&user.my,NULL); N = user.mx*user.my; dt = .5/PetscMax(user.mx,user.my); PetscOptionsGetReal(NULL,"-param",&user.param,NULL); if (user.param >= param_max || user.param <= param_min) SETERRQ(PETSC_COMM_SELF,1,"Parameter is out of range"); /* Create vectors to hold the solution and function value */ ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* Create matrix to hold Jacobian. Preallocate 5 nonzeros per row in the sparse matrix. Note that this is not the optimal strategy; see the Performance chapter of the users manual for information on preallocating memory in sparse matrices. */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,N,N,5,0,&J);CHKERRQ(ierr); /* Create timestepper context */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); /* Tell the timestepper context where to compute solutions */ ierr = TSSetSolution(ts,x);CHKERRQ(ierr); /* Provide the call-back for the nonlinear function we are evaluating. Thus whenever the timestepping routines need the function they will call this routine. Note the final argument is the application context used by the call-back functions. */ ierr = TSSetRHSFunction(ts,NULL,FormFunction,&user);CHKERRQ(ierr); /* Set the Jacobian matrix and the function used to compute Jacobians. */ ierr = TSSetRHSJacobian(ts,J,J,FormJacobian,&user);CHKERRQ(ierr); /* Form the initial guess for the problem */ ierr = FormInitialGuess(x,&user); /* This indicates that we are using pseudo timestepping to find a steady state solution to the nonlinear problem. */ ierr = TSSetType(ts,TSPSEUDO);CHKERRQ(ierr); /* Set the initial time to start at (this is arbitrary for steady state problems); and the initial timestep given above */ ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); /* Set a large number of timesteps and final duration time to insure convergence to steady state. */ ierr = TSSetDuration(ts,1000,1.e12); /* Use the default strategy for increasing the timestep */ ierr = TSPseudoSetTimeStep(ts,TSPseudoTimeStepDefault,0);CHKERRQ(ierr); /* Set any additional options from the options database. This includes all options for the nonlinear and linear solvers used internally the the timestepping routines. */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSetUp(ts);CHKERRQ(ierr); /* Perform the solve. This is where the timestepping takes place. */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); /* Get the number of steps */ ierr = TSGetTimeStepNumber(ts,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of pseudo timesteps = %D final time %4.2e\n",its,(double)ftime);CHKERRQ(ierr); /* Free the data structures constructed above */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }