static char help[] = "Solves u`` + u^{2} = f with Newton-like methods. Using\n\ matrix-free techniques with user-provided explicit preconditioner matrix.\n\n"; #include extern PetscErrorCode FormJacobian(SNES,Vec,Mat,Mat,void*); extern PetscErrorCode FormJacobianNoMatrix(SNES,Vec,Mat,Mat,void*); extern PetscErrorCode FormFunction(SNES,Vec,Vec,void*); extern PetscErrorCode FormFunctioni(void *,PetscInt,Vec,PetscScalar *); extern PetscErrorCode OtherFunctionForDifferencing(void*,Vec,Vec); extern PetscErrorCode FormInitialGuess(SNES,Vec); extern PetscErrorCode Monitor(SNES,PetscInt,PetscReal,void*); typedef struct { PetscViewer viewer; } MonitorCtx; typedef struct { PetscBool variant; } AppCtx; int main(int argc,char **argv) { SNES snes; /* SNES context */ SNESType type = SNESNEWTONLS; /* default nonlinear solution method */ Vec x,r,F,U; /* vectors */ Mat J,B; /* Jacobian matrix-free, explicit preconditioner */ AppCtx user; /* user-defined work context */ PetscScalar h,xp = 0.0,v; PetscInt its,n = 5,i; PetscErrorCode ierr; PetscBool puremf = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-variant",&user.variant);CHKERRQ(ierr); h = 1.0/(n-1); /* Set up data structures */ ierr = VecCreateSeq(PETSC_COMM_SELF,n,&x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)x,"Approximate Solution");CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); ierr = VecDuplicate(x,&F);CHKERRQ(ierr); ierr = VecDuplicate(x,&U);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)U,"Exact Solution");CHKERRQ(ierr); /* create explict matrix preconditioner */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,NULL,&B);CHKERRQ(ierr); /* Store right-hand-side of PDE and exact solution */ for (i=0; ivariant) { ierr = MatMFFDSetBase(jac,x,NULL);CHKERRQ(ierr); } ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); return 0; } PetscErrorCode FormJacobianNoMatrix(SNES snes,Vec x,Mat jac,Mat B,void *dummy) { PetscErrorCode ierr; AppCtx *user = (AppCtx*) dummy; if (user->variant) { ierr = MatMFFDSetBase(jac,x,NULL);CHKERRQ(ierr); } ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); return 0; } /* -------------------- User-defined monitor ----------------------- */ PetscErrorCode Monitor(SNES snes,PetscInt its,PetscReal fnorm,void *dummy) { PetscErrorCode ierr; MonitorCtx *monP = (MonitorCtx*) dummy; Vec x; MPI_Comm comm; ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); ierr = PetscFPrintf(comm,stdout,"iter = %D, SNES Function norm %g \n",its,(double)fnorm);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); ierr = VecView(x,monP->viewer);CHKERRQ(ierr); return 0; } /*TEST test: args: -ksp_gmres_cgs_refinement_type refine_always -snes_monitor_short test: suffix: 2 args: -variant -ksp_gmres_cgs_refinement_type refine_always -snes_monitor_short output_file: output/ex7_1.out # uses AIJ matrix to define diagonal matrix for Jacobian preconditioning test: suffix: 3 args: -variant -pc_type jacobi -snes_view -ksp_monitor # uses MATMFFD matrix to define diagonal matrix for Jacobian preconditioning test: suffix: 4 args: -variant -pc_type jacobi -puremf -snes_view -ksp_monitor TEST*/