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 "petscsnes.h" extern PetscErrorCode FormJacobian(SNES,Vec,Mat*,Mat*,MatStructure*,void*); extern PetscErrorCode FormFunction(SNES,Vec,Vec,void*); extern PetscErrorCode FormInitialGuess(SNES,Vec); extern PetscErrorCode Monitor(SNES,PetscInt,PetscReal,void *); typedef struct { PetscViewer viewer; } MonitorCtx; typedef struct { Mat precond; PetscTruth variant; } AppCtx; #undef __FUNCT__ #define __FUNCT__ "main" int main(int argc,char **argv) { SNES snes; /* SNES context */ SNESType type = SNESLS; /* default nonlinear solution method */ Vec x,r,F,U,work; /* vectors */ Mat J,B; /* Jacobian matrix-free, explicit preconditioner */ MonitorCtx monP; /* monitoring context */ AppCtx user; /* user-defined work context */ PetscScalar h,xp = 0.0,v; PetscInt its,n = 5,i; PetscErrorCode ierr; PetscInitialize(&argc,&argv,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-n",&n,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-variant",&user.variant);CHKERRQ(ierr); h = 1.0/(n-1); /* Set up data structures */ ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,400,400,&monP.viewer);CHKERRQ(ierr); 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,PETSC_NULL,&B);CHKERRQ(ierr); user.precond = B; /* Store right-hand-side of PDE and exact solution */ for (i=0; iprecond; ierr = VecGetArray(x,&xx);CHKERRQ(ierr); ierr = VecGetSize(x,&n);CHKERRQ(ierr); d = (PetscReal)(n - 1); d = d*d; i = 0; A[0] = 1.0; ierr = MatSetValues(*B,1,&i,1,&i,&A[0],INSERT_VALUES);CHKERRQ(ierr); for (i=1; ivariant) { ierr = MatSNESMFSetBase(*jac,x);CHKERRQ(ierr); } ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); return 0; } /* -------------------- User-defined monitor ----------------------- */ #undef __FUNCT__ #define __FUNCT__ "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,fnorm);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); ierr = VecView(x,monP->viewer);CHKERRQ(ierr); return 0; }