1c4762a1bSJed Brown! 2c4762a1bSJed Brown! Description: Uses the Newton method to solve a two-variable system. 3c4762a1bSJed Brown! 4c4762a1bSJed Brown 5c4762a1bSJed Brown program main 6c4762a1bSJed Brown#include <petsc/finclude/petsc.h> 7c4762a1bSJed Brown use petsc 8c4762a1bSJed Brown implicit none 9c4762a1bSJed Brown 10c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 11c4762a1bSJed Brown! Variable declarations 12c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 13c4762a1bSJed Brown! 14c4762a1bSJed Brown! Variables: 15c4762a1bSJed Brown! snes - nonlinear solver 16c4762a1bSJed Brown! ksp - linear solver 17c4762a1bSJed Brown! pc - preconditioner context 18c4762a1bSJed Brown! ksp - Krylov subspace method context 19c4762a1bSJed Brown! x, r - solution, residual vectors 20c4762a1bSJed Brown! J - Jacobian matrix 21c4762a1bSJed Brown! its - iterations for convergence 22c4762a1bSJed Brown! 23c4762a1bSJed Brown SNES snes 24c4762a1bSJed Brown PC pc 25c4762a1bSJed Brown KSP ksp 26c4762a1bSJed Brown Vec x,r 27c4762a1bSJed Brown Mat J 28c4762a1bSJed Brown SNESLineSearch linesearch 29c4762a1bSJed Brown PetscErrorCode ierr 30c4762a1bSJed Brown PetscInt its,i2,i20 31c4762a1bSJed Brown PetscMPIInt size,rank 32c4762a1bSJed Brown PetscScalar pfive 33c4762a1bSJed Brown PetscReal tol 34c4762a1bSJed Brown PetscBool setls 35956f8c0dSBarry Smith#if defined(PETSC_USE_LOG) 36c4762a1bSJed Brown PetscViewer viewer 37956f8c0dSBarry Smith#endif 38c4762a1bSJed Brown double precision threshold,oldthreshold 39c4762a1bSJed Brown 40c4762a1bSJed Brown! Note: Any user-defined Fortran routines (such as FormJacobian) 41c4762a1bSJed Brown! MUST be declared as external. 42c4762a1bSJed Brown 43c4762a1bSJed Brown external FormFunction, FormJacobian, MyLineSearch 44c4762a1bSJed Brown 45c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 46c4762a1bSJed Brown! Beginning of program 47c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 48c4762a1bSJed Brown 49d8606c27SBarry Smith PetscCallA(PetscInitialize(ierr)) 50d8606c27SBarry Smith PetscCallA(PetscLogNestedBegin(ierr)) 51c4762a1bSJed Brown threshold = 1.0 52d8606c27SBarry Smith PetscCallA(PetscLogSetThreshold(threshold,oldthreshold,ierr)) 53d8606c27SBarry Smith PetscCallMPIA(MPI_Comm_size(PETSC_COMM_WORLD,size,ierr)) 54d8606c27SBarry Smith PetscCallMPIA(MPI_Comm_rank(PETSC_COMM_WORLD,rank,ierr)) 55dcb3e689SBarry Smith PetscCheckA(size .eq. 1,PETSC_COMM_SELF,PETSC_ERR_WRONG_MPI_SIZE,'Uniprocessor example') 56c4762a1bSJed Brown 57c4762a1bSJed Brown i2 = 2 58c4762a1bSJed Brown i20 = 20 59c4762a1bSJed Brown! - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - 60c4762a1bSJed Brown! Create nonlinear solver context 61c4762a1bSJed Brown! - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - 62c4762a1bSJed Brown 63d8606c27SBarry Smith PetscCallA(SNESCreate(PETSC_COMM_WORLD,snes,ierr)) 64c4762a1bSJed Brown 65c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 66c4762a1bSJed Brown! Create matrix and vector data structures; set corresponding routines 67c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 68c4762a1bSJed Brown 69c4762a1bSJed Brown! Create vectors for solution and nonlinear function 70c4762a1bSJed Brown 71d8606c27SBarry Smith PetscCallA(VecCreateSeq(PETSC_COMM_SELF,i2,x,ierr)) 72d8606c27SBarry Smith PetscCallA(VecDuplicate(x,r,ierr)) 73c4762a1bSJed Brown 74c4762a1bSJed Brown! Create Jacobian matrix data structure 75c4762a1bSJed Brown 76d8606c27SBarry Smith PetscCallA(MatCreate(PETSC_COMM_SELF,J,ierr)) 77d8606c27SBarry Smith PetscCallA(MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,i2,i2,ierr)) 78d8606c27SBarry Smith PetscCallA(MatSetFromOptions(J,ierr)) 79d8606c27SBarry Smith PetscCallA(MatSetUp(J,ierr)) 80c4762a1bSJed Brown 81c4762a1bSJed Brown! Set function evaluation routine and vector 82c4762a1bSJed Brown 83d8606c27SBarry Smith PetscCallA(SNESSetFunction(snes,r,FormFunction,0,ierr)) 84c4762a1bSJed Brown 85c4762a1bSJed Brown! Set Jacobian matrix data structure and Jacobian evaluation routine 86c4762a1bSJed Brown 87d8606c27SBarry Smith PetscCallA(SNESSetJacobian(snes,J,J,FormJacobian,0,ierr)) 88c4762a1bSJed Brown 89c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 90c4762a1bSJed Brown! Customize nonlinear solver; set runtime options 91c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 92c4762a1bSJed Brown 93c4762a1bSJed Brown! Set linear solver defaults for this problem. By extracting the 94c4762a1bSJed Brown! KSP, KSP, and PC contexts from the SNES context, we can then 95c4762a1bSJed Brown! directly call any KSP, KSP, and PC routines to set various options. 96c4762a1bSJed Brown 97d8606c27SBarry Smith PetscCallA(SNESGetKSP(snes,ksp,ierr)) 98d8606c27SBarry Smith PetscCallA(KSPGetPC(ksp,pc,ierr)) 99d8606c27SBarry Smith PetscCallA(PCSetType(pc,PCNONE,ierr)) 100c4762a1bSJed Brown tol = 1.e-4 101*fb842aefSJose E. Roman PetscCallA(KSPSetTolerances(ksp,tol,PETSC_CURRENT_REAL,PETSC_CURRENT_REAL,i20,ierr)) 102c4762a1bSJed Brown 103c4762a1bSJed Brown! Set SNES/KSP/KSP/PC runtime options, e.g., 104c4762a1bSJed Brown! -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc> 105c4762a1bSJed Brown! These options will override those specified above as long as 106c4762a1bSJed Brown! SNESSetFromOptions() is called _after_ any other customization 107c4762a1bSJed Brown! routines. 108c4762a1bSJed Brown 109d8606c27SBarry Smith PetscCallA(SNESSetFromOptions(snes,ierr)) 110c4762a1bSJed Brown 111d8606c27SBarry Smith PetscCallA(PetscOptionsHasName(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-setls',setls,ierr)) 112c4762a1bSJed Brown 113c4762a1bSJed Brown if (setls) then 114d8606c27SBarry Smith PetscCallA(SNESGetLineSearch(snes, linesearch, ierr)) 115d8606c27SBarry Smith PetscCallA(SNESLineSearchSetType(linesearch, 'shell', ierr)) 1169bcc50f1SBarry Smith PetscCallA(SNESLineSearchShellSetApply(linesearch, MyLineSearch,0,ierr)) 117c4762a1bSJed Brown endif 118c4762a1bSJed Brown 119c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 120c4762a1bSJed Brown! Evaluate initial guess; then solve nonlinear system 121c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 122c4762a1bSJed Brown 123c4762a1bSJed Brown! Note: The user should initialize the vector, x, with the initial guess 124c4762a1bSJed Brown! for the nonlinear solver prior to calling SNESSolve(). In particular, 125c4762a1bSJed Brown! to employ an initial guess of zero, the user should explicitly set 126c4762a1bSJed Brown! this vector to zero by calling VecSet(). 127c4762a1bSJed Brown 128c4762a1bSJed Brown pfive = 0.5 129d8606c27SBarry Smith PetscCallA(VecSet(x,pfive,ierr)) 130d8606c27SBarry Smith PetscCallA(SNESSolve(snes,PETSC_NULL_VEC,x,ierr)) 13191f3e32bSBarry Smith 13291f3e32bSBarry Smith! View solver converged reason; we could instead use the option -snes_converged_reason 133d8606c27SBarry Smith PetscCallA(SNESConvergedReasonView(snes,PETSC_VIEWER_STDOUT_WORLD,ierr)) 13491f3e32bSBarry Smith 135d8606c27SBarry Smith PetscCallA(SNESGetIterationNumber(snes,its,ierr)) 136c4762a1bSJed Brown if (rank .eq. 0) then 137c4762a1bSJed Brown write(6,100) its 138c4762a1bSJed Brown endif 139c4762a1bSJed Brown 100 format('Number of SNES iterations = ',i5) 140c4762a1bSJed Brown 141c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 142c4762a1bSJed Brown! Free work space. All PETSc objects should be destroyed when they 143c4762a1bSJed Brown! are no longer needed. 144c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 145c4762a1bSJed Brown 146d8606c27SBarry Smith PetscCallA(VecDestroy(x,ierr)) 147d8606c27SBarry Smith PetscCallA(VecDestroy(r,ierr)) 148d8606c27SBarry Smith PetscCallA(MatDestroy(J,ierr)) 149d8606c27SBarry Smith PetscCallA(SNESDestroy(snes,ierr)) 150956f8c0dSBarry Smith#if defined(PETSC_USE_LOG) 151d8606c27SBarry Smith PetscCallA(PetscViewerASCIIOpen(PETSC_COMM_WORLD,'filename.xml',viewer,ierr)) 152d8606c27SBarry Smith PetscCallA(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_XML,ierr)) 153d8606c27SBarry Smith PetscCallA(PetscLogView(viewer,ierr)) 154d8606c27SBarry Smith PetscCallA(PetscViewerDestroy(viewer,ierr)) 155956f8c0dSBarry Smith#endif 156d8606c27SBarry Smith PetscCallA(PetscFinalize(ierr)) 157c4762a1bSJed Brown end 158c4762a1bSJed Brown! 159c4762a1bSJed Brown! ------------------------------------------------------------------------ 160c4762a1bSJed Brown! 161c4762a1bSJed Brown! FormFunction - Evaluates nonlinear function, F(x). 162c4762a1bSJed Brown! 163c4762a1bSJed Brown! Input Parameters: 164c4762a1bSJed Brown! snes - the SNES context 165c4762a1bSJed Brown! x - input vector 166c4762a1bSJed Brown! dummy - optional user-defined context (not used here) 167c4762a1bSJed Brown! 168c4762a1bSJed Brown! Output Parameter: 169c4762a1bSJed Brown! f - function vector 170c4762a1bSJed Brown! 171c4762a1bSJed Brown subroutine FormFunction(snes,x,f,dummy,ierr) 172c4762a1bSJed Brown use petscsnes 173c4762a1bSJed Brown implicit none 174c4762a1bSJed Brown 175c4762a1bSJed Brown SNES snes 176c4762a1bSJed Brown Vec x,f 177c4762a1bSJed Brown PetscErrorCode ierr 178c4762a1bSJed Brown integer dummy(*) 179c4762a1bSJed Brown 180c4762a1bSJed Brown! Declarations for use with local arrays 18142ce371bSBarry Smith PetscScalar,pointer :: lx_v(:),lf_v(:) 182c4762a1bSJed Brown 183c4762a1bSJed Brown! Get pointers to vector data. 18442ce371bSBarry Smith! - VecGetArrayF90() returns a pointer to the data array. 18542ce371bSBarry Smith! - You MUST call VecRestoreArrayF90() when you no longer need access to 186c4762a1bSJed Brown! the array. 187c4762a1bSJed Brown 18842ce371bSBarry Smith PetscCall(VecGetArrayReadF90(x,lx_v,ierr)) 18942ce371bSBarry Smith PetscCall(VecGetArrayF90(f,lf_v,ierr)) 190c4762a1bSJed Brown 191c4762a1bSJed Brown! Compute function 192c4762a1bSJed Brown 19342ce371bSBarry Smith lf_v(1) = lx_v(1)*lx_v(1) + lx_v(1)*lx_v(2) - 3.0 19442ce371bSBarry Smith lf_v(2) = lx_v(1)*lx_v(2) + lx_v(2)*lx_v(2) - 6.0 195c4762a1bSJed Brown 196c4762a1bSJed Brown! Restore vectors 197c4762a1bSJed Brown 19842ce371bSBarry Smith PetscCall(VecRestoreArrayReadF90(x,lx_v,ierr)) 19942ce371bSBarry Smith PetscCall(VecRestoreArrayF90(f,lf_v,ierr)) 200c4762a1bSJed Brown 201c4762a1bSJed Brown end 202c4762a1bSJed Brown 203c4762a1bSJed Brown! --------------------------------------------------------------------- 204c4762a1bSJed Brown! 205c4762a1bSJed Brown! FormJacobian - Evaluates Jacobian matrix. 206c4762a1bSJed Brown! 207c4762a1bSJed Brown! Input Parameters: 208c4762a1bSJed Brown! snes - the SNES context 209c4762a1bSJed Brown! x - input vector 210c4762a1bSJed Brown! dummy - optional user-defined context (not used here) 211c4762a1bSJed Brown! 212c4762a1bSJed Brown! Output Parameters: 213c4762a1bSJed Brown! A - Jacobian matrix 214c4762a1bSJed Brown! B - optionally different preconditioning matrix 215c4762a1bSJed Brown! 216c4762a1bSJed Brown subroutine FormJacobian(snes,X,jac,B,dummy,ierr) 217c4762a1bSJed Brown use petscsnes 218c4762a1bSJed Brown implicit none 219c4762a1bSJed Brown 220c4762a1bSJed Brown SNES snes 221c4762a1bSJed Brown Vec X 222c4762a1bSJed Brown Mat jac,B 223c4762a1bSJed Brown PetscScalar A(4) 224c4762a1bSJed Brown PetscErrorCode ierr 225c4762a1bSJed Brown PetscInt idx(2),i2 226c4762a1bSJed Brown integer dummy(*) 227c4762a1bSJed Brown 228c4762a1bSJed Brown! Declarations for use with local arrays 229c4762a1bSJed Brown 23042ce371bSBarry Smith PetscScalar,pointer :: lx_v(:) 231c4762a1bSJed Brown 232c4762a1bSJed Brown! Get pointer to vector data 233c4762a1bSJed Brown 234c4762a1bSJed Brown i2 = 2 23542ce371bSBarry Smith PetscCall(VecGetArrayReadF90(x,lx_v,ierr)) 236c4762a1bSJed Brown 237c4762a1bSJed Brown! Compute Jacobian entries and insert into matrix. 238c4762a1bSJed Brown! - Since this is such a small problem, we set all entries for 239c4762a1bSJed Brown! the matrix at once. 240c4762a1bSJed Brown! - Note that MatSetValues() uses 0-based row and column numbers 241c4762a1bSJed Brown! in Fortran as well as in C (as set here in the array idx). 242c4762a1bSJed Brown 243c4762a1bSJed Brown idx(1) = 0 244c4762a1bSJed Brown idx(2) = 1 24542ce371bSBarry Smith A(1) = 2.0*lx_v(1) + lx_v(2) 24642ce371bSBarry Smith A(2) = lx_v(1) 24742ce371bSBarry Smith A(3) = lx_v(2) 24842ce371bSBarry Smith A(4) = lx_v(1) + 2.0*lx_v(2) 249d8606c27SBarry Smith PetscCall(MatSetValues(B,i2,idx,i2,idx,A,INSERT_VALUES,ierr)) 250c4762a1bSJed Brown 251c4762a1bSJed Brown! Restore vector 252c4762a1bSJed Brown 25342ce371bSBarry Smith PetscCall(VecRestoreArrayReadF90(x,lx_v,ierr)) 254c4762a1bSJed Brown 255c4762a1bSJed Brown! Assemble matrix 256c4762a1bSJed Brown 257d8606c27SBarry Smith PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY,ierr)) 258d8606c27SBarry Smith PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY,ierr)) 259c4762a1bSJed Brown if (B .ne. jac) then 260d8606c27SBarry Smith PetscCall(MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY,ierr)) 261d8606c27SBarry Smith PetscCall(MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY,ierr)) 262c4762a1bSJed Brown endif 263c4762a1bSJed Brown 264c4762a1bSJed Brown end 265c4762a1bSJed Brown 266c4762a1bSJed Brown subroutine MyLineSearch(linesearch, lctx, ierr) 267c4762a1bSJed Brown use petscsnes 268c4762a1bSJed Brown implicit none 269c4762a1bSJed Brown 270c4762a1bSJed Brown SNESLineSearch linesearch 271c4762a1bSJed Brown SNES snes 272c4762a1bSJed Brown integer lctx 273c4762a1bSJed Brown Vec x, f,g, y, w 274c4762a1bSJed Brown PetscReal ynorm,gnorm,xnorm 275c4762a1bSJed Brown PetscErrorCode ierr 276c4762a1bSJed Brown 277c4762a1bSJed Brown PetscScalar mone 278c4762a1bSJed Brown 279c4762a1bSJed Brown mone = -1.0 280d8606c27SBarry Smith PetscCall(SNESLineSearchGetSNES(linesearch, snes, ierr)) 281d8606c27SBarry Smith PetscCall(SNESLineSearchGetVecs(linesearch, x, f, y, w, g, ierr)) 282d8606c27SBarry Smith PetscCall(VecNorm(y,NORM_2,ynorm,ierr)) 283d8606c27SBarry Smith PetscCall(VecAXPY(x,mone,y,ierr)) 284d8606c27SBarry Smith PetscCall(SNESComputeFunction(snes,x,f,ierr)) 285d8606c27SBarry Smith PetscCall(VecNorm(f,NORM_2,gnorm,ierr)) 286d8606c27SBarry Smith PetscCall(VecNorm(x,NORM_2,xnorm,ierr)) 287d8606c27SBarry Smith PetscCall(VecNorm(y,NORM_2,ynorm,ierr)) 288d8606c27SBarry Smith PetscCall(SNESLineSearchSetNorms(linesearch, xnorm, gnorm, ynorm,ierr)) 289c4762a1bSJed Brown end 290c4762a1bSJed Brown 291c4762a1bSJed Brown!/*TEST 292c4762a1bSJed Brown! 293c4762a1bSJed Brown! test: 294c4762a1bSJed Brown! args: -ksp_gmres_cgs_refinement_type refine_always -snes_monitor_short 295c4762a1bSJed Brown! requires: !single 296c4762a1bSJed Brown! 297c4762a1bSJed Brown!TEST*/ 298