Actual source code: ex44f.F90
1: #include <petsc/finclude/petscksp.h>
2: #include <petsc/finclude/petscdmda.h>
3: program main ! Solves the linear system J x = f
4: use petscksp
5: use petscdmda
6: implicit none
8: Vec x, f
9: Mat J
10: DM da
11: KSP ksp
12: PetscErrorCode ierr
14: PetscCallA(PetscInitialize(ierr))
15: PetscCallA(DMDACreate1d(MPI_COMM_WORLD, DM_BOUNDARY_NONE, 8_PETSC_INT_KIND, 1_PETSC_INT_KIND, 1_PETSC_INT_KIND, PETSC_NULL_INTEGER_ARRAY, da, ierr))
16: PetscCallA(DMSetFromOptions(da, ierr))
17: PetscCallA(DMSetUp(da, ierr))
18: PetscCallA(DMCreateGlobalVector(da, x, ierr))
19: PetscCallA(VecDuplicate(x, f, ierr))
20: PetscCallA(DMSetMatType(da, MATAIJ, ierr))
21: PetscCallA(DMCreateMatrix(da, J, ierr))
23: PetscCallA(ComputeRHS(da, f, ierr))
24: PetscCallA(ComputeMatrix(da, J, ierr))
26: PetscCallA(KSPCreate(MPI_COMM_WORLD, ksp, ierr))
27: PetscCallA(KSPSetOperators(ksp, J, J, ierr))
28: PetscCallA(KSPSetFromOptions(ksp, ierr))
29: PetscCallA(KSPSolve(ksp, f, x, ierr))
31: PetscCallA(MatDestroy(J, ierr))
32: PetscCallA(VecDestroy(x, ierr))
33: PetscCallA(VecDestroy(f, ierr))
34: PetscCallA(KSPDestroy(ksp, ierr))
35: PetscCallA(DMDestroy(da, ierr))
36: PetscCallA(PetscFinalize(ierr))
38: contains
39: subroutine ComputeRHS(da, x, ierr)
40: DM da
41: Vec x
42: PetscErrorCode, intent(out) :: ierr
43: PetscInt xs, xm, i, mx
44: PetscScalar hx
45: PetscScalar, pointer :: xx(:)
46: PetscCall(DMDAGetInfo(da, PETSC_NULL_INTEGER, mx, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, 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))
47: PetscCall(DMDAGetCorners(da, xs, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, xm, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, ierr))
48: hx = 1.0_PETSC_REAL_KIND/(mx - 1)
49: PetscCall(DMDAVecGetArray(da, x, xx, ierr))
50: do i = xs, xs + xm - 1
51: xx(i) = i*hx
52: end do
53: PetscCall(DMDAVecRestoreArray(da, x, xx, ierr))
54: end
56: subroutine ComputeMatrix(da, J, ierr)
57: Mat J
58: DM da
59: PetscErrorCode, intent(out) :: ierr
60: PetscInt xs, xm, i, mx
61: PetscScalar hx
62: PetscScalar, parameter :: one = 1.0
64: PetscCall(DMDAGetInfo(da, PETSC_NULL_INTEGER, mx, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, 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))
65: PetscCall(DMDAGetCorners(da, xs, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, xm, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, ierr))
66: hx = 1.0_PETSC_REAL_KIND/(mx - 1)
67: do i = xs, xs + xm - 1
68: if ((i == 0) .or. (i == mx - 1)) then
69: PetscCall(MatSetValue(J, i, i, one, INSERT_VALUES, ierr))
70: else
71: PetscCall(MatSetValue(J, i, i - 1, -hx, INSERT_VALUES, ierr))
72: PetscCall(MatSetValue(J, i, i + 1, -hx, INSERT_VALUES, ierr))
73: PetscCall(MatSetValue(J, i, i, 2*hx, INSERT_VALUES, ierr))
74: end if
75: end do
76: PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY, ierr))
77: PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY, ierr))
78: end
79: end program
80: !/*TEST
81: !
82: ! test:
83: ! args: -ksp_converged_reason
84: !
85: !TEST*/