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
12: program main
14: #include <petsc/finclude/petscksp.h>
15: use petscdmda
16: use petscksp
17: implicit none
19: PetscErrorCode ierr
20: DM da
21: KSP ksp
22: Vec x
23: external ComputeRHS,ComputeMatrix
24: PetscInt i1,i3
25: PetscInt ctx
27: PetscCallA(PetscInitialize(ierr))
29: i3 = 3
30: i1 = 1
31: PetscCallA(KSPCreate(PETSC_COMM_WORLD,ksp,ierr))
32: PetscCallA(DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,i3,i3,i3,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,i1,i1,PETSC_NULL_INTEGER_ARRAY,PETSC_NULL_INTEGER_ARRAY,PETSC_NULL_INTEGER_ARRAY,da,ierr))
33: PetscCallA(DMSetFromOptions(da,ierr))
34: PetscCallA(DMSetUp(da,ierr))
35: PetscCallA(KSPSetDM(ksp,da,ierr))
36: PetscCallA(KSPSetComputeRHS(ksp,ComputeRHS,ctx,ierr))
37: PetscCallA(KSPSetComputeOperators(ksp,ComputeMatrix,ctx,ierr))
39: PetscCallA(KSPSetFromOptions(ksp,ierr))
40: PetscCallA(KSPSolve(ksp,PETSC_NULL_VEC,PETSC_NULL_VEC,ierr))
41: PetscCallA(KSPGetSolution(ksp,x,ierr))
42: PetscCallA(KSPDestroy(ksp,ierr))
43: PetscCallA(DMDestroy(da,ierr))
44: PetscCallA(PetscFinalize(ierr))
46: end
48: subroutine ComputeRHS(ksp,b,ctx,ierr)
49: use petscksp
50: implicit none
52: PetscErrorCode ierr
53: PetscInt mx,my,mz
54: PetscScalar h
55: Vec b
56: KSP ksp
57: DM da
58: PetscInt ctx
60: PetscCall(KSPGetDM(ksp,da,ierr))
61: 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_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,ierr))
62: h = 1.0/real((mx-1)*(my-1)*(mz-1))
64: PetscCall(VecSet(b,h,ierr))
65: end
67: subroutine ComputeMatrix(ksp,JJ,jac,ctx,ierr)
68: use petscksp
69: implicit none
71: Mat jac,JJ
72: PetscErrorCode ierr
73: KSP ksp
74: DM da
75: PetscInt i,j,k,mx,my,mz,xm
76: PetscInt ym,zm,xs,ys,zs,i1,i7
77: PetscScalar v(7),Hx,Hy,Hz
78: PetscScalar HxHydHz,HyHzdHx
79: PetscScalar HxHzdHy
80: MatStencil row(4),col(4,7)
81: PetscInt ctx
82: i1 = 1
83: i7 = 7
84: PetscCall(KSPGetDM(ksp,da,ierr))
85: 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_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,ierr))
87: Hx = 1.0 / real(mx-1)
88: Hy = 1.0 / real(my-1)
89: Hz = 1.0 / real(mz-1)
90: HxHydHz = Hx*Hy/Hz
91: HxHzdHy = Hx*Hz/Hy
92: HyHzdHx = Hy*Hz/Hx
93: PetscCall(DMDAGetCorners(da,xs,ys,zs,xm,ym,zm,ierr))
95: do 10,k=zs,zs+zm-1
96: do 20,j=ys,ys+ym-1
97: do 30,i=xs,xs+xm-1
98: row(MatStencil_i) = i
99: row(MatStencil_j) = j
100: row(MatStencil_k) = k
101: if (i.eq.0 .or. j.eq.0 .or. k.eq.0 .or. i.eq.mx-1 .or. j.eq.my-1 .or. k.eq.mz-1) then
102: v(1) = 2.0*(HxHydHz + HxHzdHy + HyHzdHx)
103: PetscCall(MatSetValuesStencil(jac,i1,row,i1,row,v,INSERT_VALUES,ierr))
104: else
105: v(1) = -HxHydHz
106: col(MatStencil_i,1) = i
107: col(MatStencil_j,1) = j
108: col(MatStencil_k,1) = k-1
109: v(2) = -HxHzdHy
110: col(MatStencil_i,2) = i
111: col(MatStencil_j,2) = j-1
112: col(MatStencil_k,2) = k
113: v(3) = -HyHzdHx
114: col(MatStencil_i,3) = i-1
115: col(MatStencil_j,3) = j
116: col(MatStencil_k,3) = k
117: v(4) = 2.0*(HxHydHz + HxHzdHy + HyHzdHx)
118: col(MatStencil_i,4) = i
119: col(MatStencil_j,4) = j
120: col(MatStencil_k,4) = k
121: v(5) = -HyHzdHx
122: col(MatStencil_i,5) = i+1
123: col(MatStencil_j,5) = j
124: col(MatStencil_k,5) = k
125: v(6) = -HxHzdHy
126: col(MatStencil_i,6) = i
127: col(MatStencil_j,6) = j+1
128: col(MatStencil_k,6) = k
129: v(7) = -HxHydHz
130: col(MatStencil_i,7) = i
131: col(MatStencil_j,7) = j
132: col(MatStencil_k,7) = k+1
133: PetscCall(MatSetValuesStencil(jac,i1,row,i7,col,v,INSERT_VALUES,ierr))
134: endif
135: 30 continue
136: 20 continue
137: 10 continue
139: PetscCall(MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY,ierr))
140: PetscCall(MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY,ierr))
141: end
143: !/*TEST
144: !
145: ! test:
146: ! 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
147: ! requires: !single
148: ! output_file: output/ex22_1.out
149: !
150: !TEST*/