static char help[] = "Newton method to solve u'' + u^{2} = f, sequentially.\n\ This example employs a user-defined monitoring routine.\n\n"; /* Include "petscdraw.h" so that we can use PETSc drawing routines. Include "petscsnes.h" so that we can use SNES solvers. Note that this file automatically includes: petscsys.h - base PETSc routines petscvec.h - vectors petscmat.h - matrices petscis.h - index sets petscksp.h - Krylov subspace methods petscviewer.h - viewers petscpc.h - preconditioners petscksp.h - linear solvers */ #include /* User-defined routines */ extern PetscErrorCode FormJacobian(SNES,Vec,Mat,Mat,void*); extern PetscErrorCode FormFunction(SNES,Vec,Vec,void*); extern PetscErrorCode FormInitialGuess(Vec); extern PetscErrorCode Monitor(SNES,PetscInt,PetscReal,void*); /* User-defined context for monitoring */ typedef struct { PetscViewer viewer; } MonitorCtx; int main(int argc,char **argv) { SNES snes; /* SNES context */ Vec x,r,F,U; /* vectors */ Mat J; /* Jacobian matrix */ MonitorCtx monP; /* monitoring context */ PetscInt its,n = 5,i,maxit,maxf; PetscMPIInt size; PetscScalar h,xp,v,none = -1.0; PetscReal abstol,rtol,stol,norm; PetscCall(PetscInitialize(&argc,&argv,(char*)0,help)); PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size)); PetscCheck(size == 1,PETSC_COMM_SELF,PETSC_ERR_WRONG_MPI_SIZE,"This is a uniprocessor example only!"); PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL)); h = 1.0/(n-1); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscCall(SNESCreate(PETSC_COMM_WORLD,&snes)); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create vector data structures; set function evaluation routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Note that we form 1 vector from scratch and then duplicate as needed. */ PetscCall(VecCreate(PETSC_COMM_WORLD,&x)); PetscCall(VecSetSizes(x,PETSC_DECIDE,n)); PetscCall(VecSetFromOptions(x)); PetscCall(VecDuplicate(x,&r)); PetscCall(VecDuplicate(x,&F)); PetscCall(VecDuplicate(x,&U)); /* Set function evaluation routine and vector */ PetscCall(SNESSetFunction(snes,r,FormFunction,(void*)F)); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix data structure; set Jacobian evaluation routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscCall(MatCreate(PETSC_COMM_WORLD,&J)); PetscCall(MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,n,n)); PetscCall(MatSetFromOptions(J)); PetscCall(MatSeqAIJSetPreallocation(J,3,NULL)); /* 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 */ PetscCall(SNESSetJacobian(snes,J,J,FormJacobian,NULL)); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Set an optional user-defined monitoring routine */ PetscCall(PetscViewerDrawOpen(PETSC_COMM_WORLD,0,0,0,0,400,400,&monP.viewer)); PetscCall(SNESMonitorSet(snes,Monitor,&monP,0)); /* Set names for some vectors to facilitate monitoring (optional) */ PetscCall(PetscObjectSetName((PetscObject)x,"Approximate Solution")); PetscCall(PetscObjectSetName((PetscObject)U,"Exact Solution")); /* Set SNES/KSP/KSP/PC runtime options, e.g., -snes_view -snes_monitor -ksp_type -pc_type */ PetscCall(SNESSetFromOptions(snes)); /* Print parameters used for convergence testing (optional) ... just to demonstrate this routine; this information is also printed with the option -snes_view */ PetscCall(SNESGetTolerances(snes,&abstol,&rtol,&stol,&maxit,&maxf)); PetscCall(PetscPrintf(PETSC_COMM_WORLD,"atol=%g, rtol=%g, stol=%g, maxit=%D, maxf=%D\n",(double)abstol,(double)rtol,(double)stol,maxit,maxf)); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize application: Store right-hand-side of PDE and exact solution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ xp = 0.0; for (i=0; iviewer)); return 0; } /*TEST test: args: -nox -snes_monitor_cancel -snes_monitor_short -snes_view -pc_type jacobi -ksp_gmres_cgs_refinement_type refine_always test: suffix: 2 args: -nox -snes_monitor_cancel -snes_monitor_short -snes_type newtontr -snes_view requires: !single test: suffix: 3 args: -nox -malloc no -options_left no -snes_monitor_cancel -snes_monitor_short -snes_view -pc_type jacobi -ksp_gmres_cgs_refinement_type refine_always test: suffix: 4 args: -nox -snes_monitor_cancel -snes_monitor_short -snes_type newtontrdc -snes_view requires: !single TEST*/