Actual source code: ex22f.F90

  1: !
  2: !   Laplacian in 3D. Modeled by the partial differential equation
  3: !
  4: !   Laplacian u = 1,0 < x,y,z < 1,
  5: !
  6: !   with boundary conditions
  7: !
  8: !   u = 1 for x = 0, x = 1, y = 0, y = 1, z = 0, z = 1.
  9: !
 10: !   This uses multigrid to solve the linear system
 11: #include <petsc/finclude/petscdmda.h>
 12: #include <petsc/finclude/petscksp.h>
 13: module ex22fmodule
 14:   use petscksp
 15:   use petscdmda
 16:   implicit none

 18: contains
 19:   subroutine ComputeRHS(ksp, b, ctx, ierr)
 20:     PetscErrorCode, intent(out) :: ierr
 21:     PetscInt mx, my, mz
 22:     PetscScalar h
 23:     Vec b
 24:     KSP ksp
 25:     DM da
 26:     PetscInt ctx

 28:     PetscCall(KSPGetDM(ksp, da, ierr))
 29:     PetscCall(DMDAGetInfo(da, PETSC_NULL_INTEGER, mx, my, mz, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_DMBOUNDARYTYPE, PETSC_NULL_DMBOUNDARYTYPE, PETSC_NULL_DMBOUNDARYTYPE, PETSC_NULL_DMDASTENCILTYPE, ierr))
 30:     h = 1.0/real((mx - 1)*(my - 1)*(mz - 1))

 32:     PetscCall(VecSet(b, h, ierr))
 33:   end

 35:   subroutine ComputeMatrix(ksp, JJ, jac, ctx, ierr)
 36:     Mat jac, JJ
 37:     PetscErrorCode ierr
 38:     KSP ksp
 39:     DM da
 40:     PetscInt i, j, k, mx, my, mz, xm
 41:     PetscInt ym, zm, xs, ys, zs
 42:     PetscScalar v(7), Hx, Hy, Hz
 43:     PetscScalar HxHydHz, HyHzdHx
 44:     PetscScalar HxHzdHy
 45:     MatStencil row(1), col(7)
 46:     PetscInt ctx
 47:     PetscCall(KSPGetDM(ksp, da, ierr))
 48:     PetscCall(DMDAGetInfo(da, PETSC_NULL_INTEGER, mx, my, mz, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, PETSC_NULL_DMBOUNDARYTYPE, PETSC_NULL_DMBOUNDARYTYPE, PETSC_NULL_DMBOUNDARYTYPE, PETSC_NULL_DMDASTENCILTYPE, ierr))

 50:     Hx = 1.0/real(mx - 1)
 51:     Hy = 1.0/real(my - 1)
 52:     Hz = 1.0/real(mz - 1)
 53:     HxHydHz = Hx*Hy/Hz
 54:     HxHzdHy = Hx*Hz/Hy
 55:     HyHzdHx = Hy*Hz/Hx
 56:     PetscCall(DMDAGetCorners(da, xs, ys, zs, xm, ym, zm, ierr))

 58:     do k = zs, zs + zm - 1
 59:       do j = ys, ys + ym - 1
 60:         do i = xs, xs + xm - 1
 61:           row(1)%i = i
 62:           row(1)%j = j
 63:           row(1)%k = k
 64:           if (i == 0 .or. j == 0 .or. k == 0 .or. i == mx - 1 .or. j == my - 1 .or. k == mz - 1) then
 65:             v(1) = 2.0*(HxHydHz + HxHzdHy + HyHzdHx)
 66:             PetscCall(MatSetValuesStencil(jac, 1_PETSC_INT_KIND, row, 1_PETSC_INT_KIND, row, v, INSERT_VALUES, ierr))
 67:           else
 68:             v(1) = -HxHydHz
 69:             col(1)%i = i
 70:             col(1)%j = j
 71:             col(1)%k = k - 1
 72:             v(2) = -HxHzdHy
 73:             col(2)%i = i
 74:             col(2)%j = j - 1
 75:             col(2)%k = k
 76:             v(3) = -HyHzdHx
 77:             col(3)%i = i - 1
 78:             col(3)%j = j
 79:             col(3)%k = k
 80:             v(4) = 2.0*(HxHydHz + HxHzdHy + HyHzdHx)
 81:             col(4)%i = i
 82:             col(4)%j = j
 83:             col(4)%k = k
 84:             v(5) = -HyHzdHx
 85:             col(5)%i = i + 1
 86:             col(5)%j = j
 87:             col(5)%k = k
 88:             v(6) = -HxHzdHy
 89:             col(6)%i = i
 90:             col(6)%j = j + 1
 91:             col(6)%k = k
 92:             v(7) = -HxHydHz
 93:             col(7)%i = i
 94:             col(7)%j = j
 95:             col(7)%k = k + 1
 96:             PetscCall(MatSetValuesStencil(jac, 1_PETSC_INT_KIND, row, 7_PETSC_INT_KIND, col, v, INSERT_VALUES, ierr))
 97:           end if
 98:         end do
 99:       end do
100:     end do

102:     PetscCall(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY, ierr))
103:     PetscCall(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY, ierr))
104:   end
105: end module ex22fmodule

107: program main
108:   use ex22fmodule
109:   implicit none

111:   PetscErrorCode ierr
112:   DM da
113:   KSP ksp
114:   Vec x
115:   PetscInt ctx

117:   PetscCallA(PetscInitialize(ierr))

119:   PetscCallA(KSPCreate(PETSC_COMM_WORLD, ksp, ierr))
120:   PetscCallA(DMDACreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, 3_PETSC_INT_KIND, 3_PETSC_INT_KIND, 3_PETSC_INT_KIND, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, 1_PETSC_INT_KIND, 1_PETSC_INT_KIND, PETSC_NULL_INTEGER_ARRAY, PETSC_NULL_INTEGER_ARRAY, PETSC_NULL_INTEGER_ARRAY, da, ierr))
121:   PetscCallA(DMSetFromOptions(da, ierr))
122:   PetscCallA(DMSetUp(da, ierr))
123:   PetscCallA(KSPSetDM(ksp, da, ierr))
124:   PetscCallA(KSPSetComputeRHS(ksp, ComputeRHS, ctx, ierr))
125:   PetscCallA(KSPSetComputeOperators(ksp, ComputeMatrix, ctx, ierr))

127:   PetscCallA(KSPSetFromOptions(ksp, ierr))
128:   PetscCallA(KSPSolve(ksp, PETSC_NULL_VEC, PETSC_NULL_VEC, ierr))
129:   PetscCallA(KSPGetSolution(ksp, x, ierr))
130:   PetscCallA(KSPDestroy(ksp, ierr))
131:   PetscCallA(DMDestroy(da, ierr))
132:   PetscCallA(PetscFinalize(ierr))

134: end

136: !/*TEST
137: !
138: !   test:
139: !      args: -pc_mg_type full -ksp_monitor_short -mg_levels_ksp_monitor_short -mg_levels_ksp_norm_type preconditioned -pc_type mg -da_refine 2 -ksp_type fgmres
140: !      requires: !single
141: !      output_file: output/ex22_1.out
142: !
143: !TEST*/