static char help[] = "Newton method to solve u'' + u^{2} = f, sequentially.\n\ This example employs a user-defined monitoring routine.\n\n"; /*T Concepts: SNES^basic uniprocessor example Concepts: SNES^setting a user-defined monitoring routine Processors: 1 T*/ /* 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*); extern PetscErrorCode FormFunction_SNES(SNES snes,Vec x, Vec r,void* ctx){ FormFunction(snes,x,r,ctx); return 0; } extern PetscErrorCode FormFunction_MFFD(void*snes_ctx,Vec x, Vec r){ SNES snes = (SNES) snes_ctx; void *ctx; SNESGetFunction(snes,NULL,NULL,&ctx); FormFunction(snes,x,r,ctx); return 0; } PETSC_EXTERN PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType); PETSC_EXTERN PetscErrorCode MatMFFDSetBase_MFFD(Mat,Vec,Vec); PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt) { PetscErrorCode ierr; SNES snes; Vec u,f; PetscFunctionBegin; ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr); ierr = MatSNESMFGetSNES(J,&snes);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); ierr = SNESGetFunction(snes,&f,NULL,NULL);CHKERRQ(ierr); ierr = MatMFFDSetBase_MFFD(J,u,f);CHKERRQ(ierr); PetscFunctionReturn(0); } /* 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 */ PetscErrorCode ierr; PetscInt its,n = 5,i,maxit,maxf; PetscMPIInt size; PetscScalar h,xp,v,none = -1.0; PetscReal abstol,rtol,stol,norm; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 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,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_SNES,(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,NULL,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 -pc_type */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetUp(snes);CHKERRQ(ierr); Mat Jacobian; ierr = SNESGetJacobian(snes,&Jacobian,NULL,NULL,NULL);CHKERRQ(ierr); ierr = MatMFFDSetFunction(Jacobian,FormFunction_MFFD,(void*)snes);CHKERRQ(ierr); ierr = MatShellSetOperation(Jacobian,MATOP_ASSEMBLY_END,(void (*)(void))MatAssemblyEnd_SNESMF);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",(double)abstol,(double)rtol,(double)stol,maxit,maxf);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize application: Store right-hand-side of PDE and exact solution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ xp = 0.0; for (i=0; iviewer);CHKERRQ(ierr);*/ 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 -snes_monitor_cancel -snes_monitor_short -malloc no -snes_view -pc_type jacobi -ksp_gmres_cgs_refinement_type refine_always TEST*/