static char help[] = "Newton method to solve u'' + u^{2} = f, sequentially.\n\ This example employs a user-defined reasonview routine.\n\n"; /*T Concepts: SNES^basic uniprocessor example Concepts: SNES^setting a user-defined reasonview routine Processors: 1 T*/ #include /* User-defined routines */ PETSC_EXTERN PetscErrorCode FormJacobian(SNES,Vec,Mat,Mat,void*); PETSC_EXTERN PetscErrorCode FormFunction(SNES,Vec,Vec,void*); PETSC_EXTERN PetscErrorCode FormInitialGuess(Vec); PETSC_EXTERN PetscErrorCode MySNESConvergedReasonView(SNES,void*); PETSC_EXTERN PetscErrorCode MyKSPConvergedReasonView(KSP,void*); /* User-defined context for monitoring */ typedef struct { PetscViewer viewer; } ReasonViewCtx; int main(int argc,char **argv) { SNES snes; /* SNES context */ KSP ksp; /* KSP context */ Vec x,r,F,U; /* vectors */ Mat J; /* Jacobian matrix */ ReasonViewCtx monP; /* monitoring context */ PetscErrorCode ierr; PetscInt its,n = 5,i; PetscMPIInt size; PetscScalar h,xp,v; MPI_Comm comm; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(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); comm = PETSC_COMM_WORLD; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(comm,&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(comm,&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(comm,&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 reasonview routine */ ierr = PetscViewerASCIIGetStdout(comm,&monP.viewer);CHKERRQ(ierr); /* Just make sure we can not repeat addding the same function * PETSc will be able to igore the repeated function */ for (i=0; i<4; i++){ ierr = SNESConvergedReasonViewSet(snes,MySNESConvergedReasonView,&monP,0);CHKERRQ(ierr); } ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); /* Just make sure we can not repeat addding the same function * PETSc will be able to igore the repeated function */ for (i=0; i<4; i++){ ierr = KSPConvergedReasonViewSet(ksp,MyKSPConvergedReasonView,&monP,0);CHKERRQ(ierr); } /* Set SNES/KSP/KSP/PC runtime options, e.g., -snes_view -snes_monitor -ksp_type -pc_type */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize application: Store right-hand-side of PDE and exact solution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ xp = 0.0; for (i=0; iviewer; SNESConvergedReason reason; const char *strreason; ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = SNESGetConvergedReasonString(snes,&strreason);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Customized SNES converged reason view\n");CHKERRQ(ierr); ierr = PetscViewerASCIIAddTab(viewer,1);CHKERRQ(ierr); if (reason > 0) { ierr = PetscViewerASCIIPrintf(viewer,"Converged due to %s\n",strreason);CHKERRQ(ierr); } else if (reason <= 0) { ierr = PetscViewerASCIIPrintf(viewer,"Did not converge due to %s\n",strreason);CHKERRQ(ierr); } ierr = PetscViewerASCIISubtractTab(viewer,1);CHKERRQ(ierr); return 0; } PetscErrorCode MyKSPConvergedReasonView(KSP ksp,void *ctx) { PetscErrorCode ierr; ReasonViewCtx *monP = (ReasonViewCtx*) ctx; PetscViewer viewer = monP->viewer; KSPConvergedReason reason; const char *reasonstr; ierr = KSPGetConvergedReason(ksp,&reason);CHKERRQ(ierr); ierr = KSPGetConvergedReasonString(ksp,&reasonstr);CHKERRQ(ierr); ierr = PetscViewerASCIIAddTab(viewer,2);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Customized KSP converged reason view\n");CHKERRQ(ierr); ierr = PetscViewerASCIIAddTab(viewer,1);CHKERRQ(ierr); if (reason > 0) { ierr = PetscViewerASCIIPrintf(viewer,"Converged due to %s\n",reasonstr);CHKERRQ(ierr); } else if (reason <= 0) { ierr = PetscViewerASCIIPrintf(viewer,"Did not converge due to %s\n",reasonstr);CHKERRQ(ierr); } ierr = PetscViewerASCIISubtractTab(viewer,3);CHKERRQ(ierr); return 0; } /*TEST test: suffix: 1 nsize: 1 test: suffix: 2 nsize: 1 args: -ksp_converged_reason_view_cancel test: suffix: 3 nsize: 1 args: -ksp_converged_reason_view_cancel -ksp_converged_reason test: suffix: 4 nsize: 1 args: -snes_converged_reason_view_cancel test: suffix: 5 nsize: 1 args: -snes_converged_reason_view_cancel -snes_converged_reason TEST*/