Actual source code: ex45f.F
petsc-3.3-p7 2013-05-11
1: program main
2: implicit none
4: #include <finclude/petscsys.h>
5: #include <finclude/petscvec.h>
6: #include <finclude/petscmat.h>
7: #include <finclude/petscpc.h>
8: #include <finclude/petscksp.h>
9: #include <finclude/petscdm.h>
10: #include <finclude/petscdmda.h>
12: PetscInt is,js,iw,jw
13: PetscErrorCode ierr
14: KSP ksp
15: DM dm
16: external ComputeRHS,ComputeMatrix,ComputeInitialGuess
18: call PetscInitialize(PETSC_NULL_CHARACTER,ierr)
19: call KSPCreate(MPI_COMM_WORLD,ksp,ierr)
20: call DMDACreate2D(MPI_COMM_WORLD, DMDA_BOUNDARY_NONE, &
21: & DMDA_BOUNDARY_NONE, DMDA_STENCIL_STAR, -3,-3, PETSC_DECIDE, &
22: & PETSC_DECIDE,1,1, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, &
23: & dm, ierr)
24: call DMSetInitialGuess(dm,ComputeInitialGuess,ierr)
25: call KSPSetComputeRHS(ksp,ComputeRHS,PETSC_NULL_OBJECT,ierr)
26: call KSPSetComputeOperators(ksp,ComputeMatrix, &
27: & PETSC_NULL_OBJECT,ierr)
28: call KSPSetDM(ksp,dm,ierr)
29: call DMDAGetCorners(dm,is,js,PETSC_NULL_INTEGER,iw,jw, &
30: & PETSC_NULL_INTEGER,ierr)
31: call KSPSetFromOptions(ksp,ierr)
32: call KSPSetUp(ksp,ierr)
33: call KSPSolve(ksp,PETSC_NULL_OBJECT,PETSC_NULL_OBJECT,ierr)
34: call KSPDestroy(ksp,ierr)
35: call DMDestroy(dm,ierr)
36: call PetscFinalize(ierr)
37: end
40: subroutine ComputeInitialGuess(dm,b,ierr)
41: implicit none
42: PetscErrorCode ierr
43: DM dm
44: Vec b
45: PetscScalar h
46: h=0.0
47: call VecSet(b,h,ierr)
48: end subroutine
50: subroutine ComputeRHS(ksp,b,dummy,ierr)
51: implicit none
52: PetscErrorCode ierr
53: KSP ksp
54: Vec b
55: integer dummy(*)
56: PetscScalar h
57: h=1.0
58: call VecSet(b,h,ierr)
59: end subroutine
61: subroutine ComputeMatrix(ksp,A,B,str,dummy,ierr)
62: implicit none
63: #include <finclude/petscsys.h>
64: #include <finclude/petscvec.h>
65: #include <finclude/petscmat.h>
66: PetscErrorCode ierr
67: KSP ksp
68: Mat A,B
69: MatStructure str
70: integer dummy(*)
71: DM dm
73: PetscInt i,j,mx,my,xm
74: PetscInt ym,xs,ys,i1,i5
75: PetscScalar v(5),Hx,Hy
76: PetscScalar HxdHy,HydHx
77: MatStencil row(4),col(4,5)
79: i1 = 1
80: i5 = 5
81: call KSPGetDM(ksp,dm,ierr)
82: call DMDAGetInfo(dm,PETSC_NULL_INTEGER,mx,my,PETSC_NULL_INTEGER, &
83: & PETSC_NULL_INTEGER,PETSC_NULL_INTEGER, &
84: & PETSC_NULL_INTEGER,PETSC_NULL_INTEGER, &
85: & PETSC_NULL_INTEGER,PETSC_NULL_INTEGER, &
86: & PETSC_NULL_INTEGER,PETSC_NULL_INTEGER, &
87: & PETSC_NULL_INTEGER,ierr)
89: Hx = 1.d0 / (mx-1)
90: Hy = 1.d0 / (my-1)
91: HxdHy = Hx/Hy
92: HydHx = Hy/Hx
93: call DMDAGetCorners(dm,xs,ys,PETSC_NULL_INTEGER,xm,ym, &
94: & PETSC_NULL_INTEGER,ierr)
95: do 10,j=ys,ys+ym-1
96: do 20,i=xs,xs+xm-1
97: row(MatStencil_i) = i
98: row(MatStencil_j) = j
99: if (i.eq.0 .or. j.eq.0 .or. i.eq.mx-1 .or. j.eq.my-1 ) then
100: v(1) = 2.d0*(HxdHy + HydHx)
101: call MatSetValuesStencil(B,i1,row,i1,row,v, &
102: & INSERT_VALUES,ierr)
103: else
104: v(1) = -HxdHy
105: col(MatStencil_i,1) = i
106: col(MatStencil_j,1) = j-1
107: v(2) = -HydHx
108: col(MatStencil_i,2) = i-1
109: col(MatStencil_j,2) = j
110: v(3) = 2.d0*(HxdHy + HydHx)
111: col(MatStencil_i,3) = i
112: col(MatStencil_j,3) = j
113: v(4) = -HydHx
114: col(MatStencil_i,4) = i+1
115: col(MatStencil_j,4) = j
116: v(5) = -HxdHy
117: col(MatStencil_i,5) = i
118: col(MatStencil_j,5) = j+1
119: call MatSetValuesStencil(B,i1,row,i5,col,v, &
120: & INSERT_VALUES,ierr)
121: endif
122: 20 continue
123: 10 continue
124: call MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY,ierr)
125: call MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY,ierr)
126: if ( A .ne. B) then
127: call MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY,ierr)
128: call MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY,ierr)
129: endif
130: end subroutine