Actual source code: ex21f.F90

  1: !
  2: !
  3: !     Solves the problem A x - x^3 + 1 = 0 via Picard iteration
  4: !
  5: #include <petsc/finclude/petscsnes.h>
  6: module ex21fmodule
  7:   use petscsnes
  8:   implicit none
  9:   type userctx
 10:     Mat A
 11:   end type userctx
 12: contains
 13:   subroutine FormFunction(snes, x, f, user, ierr)
 14:     SNES snes
 15:     Vec x, f
 16:     type(userctx) user
 17:     PetscErrorCode, intent(out) :: ierr
 18:     PetscInt n
 19:     PetscScalar, pointer :: xx(:), ff(:)

 21:     PetscCallA(MatMult(user%A, x, f, ierr))
 22:     PetscCallA(VecGetArray(f, ff, ierr))
 23:     PetscCallA(VecGetArrayRead(x, xx, ierr))
 24:     PetscCallA(VecGetLocalSize(x, n, ierr))
 25:     ff(1:n) = ff(1:n) - xx(1:n)**4 + 1.0
 26:     PetscCallA(VecRestoreArray(f, ff, ierr))
 27:     PetscCallA(VecRestoreArrayRead(x, xx, ierr))
 28:   end subroutine

 30: ! The matrix is constant so no need to recompute it
 31:   subroutine FormJacobian(snes, x, jac, jacb, user, ierr)
 32:     SNES snes
 33:     Vec x
 34:     type(userctx) user
 35:     Mat jac, jacb
 36:     PetscErrorCode, intent(out) :: ierr

 38:     ierr = 0
 39:   end subroutine
 40: end module ex21fmodule

 42: program main
 43:   use petscsnes
 44:   use ex21fmodule
 45:   implicit none
 46:   SNES snes
 47:   PetscErrorCode ierr
 48:   Vec res, x
 49:   type(userctx) user
 50:   PetscScalar val

 52:   PetscCallA(PetscInitialize(ierr))

 54:   PetscCallA(MatCreateSeqAIJ(PETSC_COMM_SELF, 2_PETSC_INT_KIND, 2_PETSC_INT_KIND, 2_PETSC_INT_KIND, PETSC_NULL_INTEGER_ARRAY, user%A, ierr))
 55:   val = 2.0
 56:   PetscCallA(MatSetValues(user%A, 1_PETSC_INT_KIND, [0_PETSC_INT_KIND], 1_PETSC_INT_KIND, [0_PETSC_INT_KIND], [val], INSERT_VALUES, ierr))
 57:   val = -1.0
 58:   PetscCallA(MatSetValues(user%A, 1_PETSC_INT_KIND, [0_PETSC_INT_KIND], 1_PETSC_INT_KIND, [1_PETSC_INT_KIND], [val], INSERT_VALUES, ierr))
 59:   val = -1.0
 60:   PetscCallA(MatSetValues(user%A, 1_PETSC_INT_KIND, [1_PETSC_INT_KIND], 1_PETSC_INT_KIND, [0_PETSC_INT_KIND], [val], INSERT_VALUES, ierr))
 61:   val = 1.0
 62:   PetscCallA(MatSetValues(user%A, 1_PETSC_INT_KIND, [1_PETSC_INT_KIND], 1_PETSC_INT_KIND, [1_PETSC_INT_KIND], [val], INSERT_VALUES, ierr))
 63:   PetscCallA(MatAssemblyBegin(user%A, MAT_FINAL_ASSEMBLY, ierr))
 64:   PetscCallA(MatAssemblyEnd(user%A, MAT_FINAL_ASSEMBLY, ierr))

 66:   PetscCallA(MatCreateVecs(user%A, x, res, ierr))

 68:   PetscCallA(SNESCreate(PETSC_COMM_SELF, snes, ierr))
 69:   PetscCallA(SNESSetPicard(snes, res, FormFunction, user%A, user%A, FormJacobian, user, ierr))
 70:   PetscCallA(SNESSetFromOptions(snes, ierr))
 71:   PetscCallA(SNESSolve(snes, PETSC_NULL_VEC, x, ierr))
 72:   PetscCallA(VecDestroy(x, ierr))
 73:   PetscCallA(VecDestroy(res, ierr))
 74:   PetscCallA(MatDestroy(user%A, ierr))
 75:   PetscCallA(SNESDestroy(snes, ierr))
 76:   PetscCallA(PetscFinalize(ierr))
 77: end

 79: !/*TEST
 80: !
 81: !   test:
 82: !     nsize: 1
 83: !     requires: !single
 84: !     args: -snes_monitor -snes_converged_reason -snes_view -pc_type lu
 85: !
 86: !TEST*/