xref: /petsc/src/ksp/pc/tests/ex9f.F90 (revision 9b88ac225e01f016352a5f4cd90e158abe5f5675)
1c4762a1bSJed Brown!
2a5b23f4aSJose E. Roman!   Description: Tests PCFieldSplitGetIS and PCFieldSplitSetIS from Fortran.
3c4762a1bSJed Brown!
4c4762a1bSJed Brown#include <petsc/finclude/petscksp.h>
5c5e229c2SMartin Diehlprogram main
6c4762a1bSJed Brown  use petscksp
7c4762a1bSJed Brown  implicit none
8c4762a1bSJed Brown
9c4762a1bSJed Brown  Vec x, b, u
10c4762a1bSJed Brown  Mat A
11c4762a1bSJed Brown  KSP ksp
12c4762a1bSJed Brown  PC pc
13ccfd86f1SBarry Smith  PetscReal norm
14c4762a1bSJed Brown  PetscErrorCode ierr
15c4762a1bSJed Brown  PetscInt i, n, col(3), its, i1, i2, i3
16e41f517fSBarry Smith  PetscInt ione, izero, nksp
17c4762a1bSJed Brown  PetscBool flg
18c4762a1bSJed Brown  PetscMPIInt size
19c4762a1bSJed Brown  PetscScalar none, one, value(3)
20e41f517fSBarry Smith  KSP, pointer :: subksp(:)
21e41f517fSBarry Smith
22c4762a1bSJed Brown  IS isin, isout
23c4762a1bSJed Brown
24c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
25c4762a1bSJed Brown!                 Beginning of program
26c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
27c4762a1bSJed Brown
28d8606c27SBarry Smith  PetscCallA(PetscInitialize(ierr))
29d8606c27SBarry Smith  PetscCallMPIA(MPI_Comm_size(PETSC_COMM_WORLD, size, ierr))
304820e4eaSBarry Smith  PetscCheckA(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, 'This is a uniprocessor example only')
31c4762a1bSJed Brown  none = -1.0
32c4762a1bSJed Brown  one = 1.0
33c4762a1bSJed Brown  n = 10
34c4762a1bSJed Brown  i1 = 1
35c4762a1bSJed Brown  i2 = 2
36c4762a1bSJed Brown  i3 = 3
37d8606c27SBarry Smith  PetscCallA(PetscOptionsGetInt(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-n', n, flg, ierr))
38c4762a1bSJed Brown
39c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
40c4762a1bSJed Brown!         Compute the matrix and right-hand-side vector that define
41c4762a1bSJed Brown!         the linear system, Ax = b.
42c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
43c4762a1bSJed Brown
44c4762a1bSJed Brown!  Create matrix.  When using MatCreate(), the matrix format can
45c4762a1bSJed Brown!  be specified at runtime.
46c4762a1bSJed Brown
47d8606c27SBarry Smith  PetscCallA(MatCreate(PETSC_COMM_WORLD, A, ierr))
48d8606c27SBarry Smith  PetscCallA(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n, ierr))
49d8606c27SBarry Smith  PetscCallA(MatSetFromOptions(A, ierr))
50d8606c27SBarry Smith  PetscCallA(MatSetUp(A, ierr))
51c4762a1bSJed Brown
52c4762a1bSJed Brown!  Assemble matrix.
53c4762a1bSJed Brown!   - Note that MatSetValues() uses 0-based row and column numbers
54c4762a1bSJed Brown!     in Fortran as well as in C (as set here in the array "col").
55c4762a1bSJed Brown
56c4762a1bSJed Brown  value(1) = -1.0
57c4762a1bSJed Brown  value(2) = 2.0
58c4762a1bSJed Brown  value(3) = -1.0
59*ceeae6b5SMartin Diehl  do i = 1, n - 2
60c4762a1bSJed Brown    col(1) = i - 1
61c4762a1bSJed Brown    col(2) = i
62c4762a1bSJed Brown    col(3) = i + 1
635d83a8b1SBarry Smith    PetscCallA(MatSetValues(A, i1, [i], i3, col, value, INSERT_VALUES, ierr))
64*ceeae6b5SMartin Diehl  end do
65c4762a1bSJed Brown  i = n - 1
66c4762a1bSJed Brown  col(1) = n - 2
67c4762a1bSJed Brown  col(2) = n - 1
685d83a8b1SBarry Smith  PetscCallA(MatSetValues(A, i1, [i], i2, col, value, INSERT_VALUES, ierr))
69c4762a1bSJed Brown  i = 0
70c4762a1bSJed Brown  col(1) = 0
71c4762a1bSJed Brown  col(2) = 1
72c4762a1bSJed Brown  value(1) = 2.0
73c4762a1bSJed Brown  value(2) = -1.0
745d83a8b1SBarry Smith  PetscCallA(MatSetValues(A, i1, [i], i2, col, value, INSERT_VALUES, ierr))
75d8606c27SBarry Smith  PetscCallA(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY, ierr))
76d8606c27SBarry Smith  PetscCallA(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY, ierr))
77c4762a1bSJed Brown
78c4762a1bSJed Brown!  Create vectors.  Note that we form 1 vector from scratch and
79c4762a1bSJed Brown!  then duplicate as needed.
80c4762a1bSJed Brown
81d8606c27SBarry Smith  PetscCallA(VecCreate(PETSC_COMM_WORLD, x, ierr))
82d8606c27SBarry Smith  PetscCallA(VecSetSizes(x, PETSC_DECIDE, n, ierr))
83d8606c27SBarry Smith  PetscCallA(VecSetFromOptions(x, ierr))
84d8606c27SBarry Smith  PetscCallA(VecDuplicate(x, b, ierr))
85d8606c27SBarry Smith  PetscCallA(VecDuplicate(x, u, ierr))
86c4762a1bSJed Brown
87c4762a1bSJed Brown!  Set exact solution; then compute right-hand-side vector.
88c4762a1bSJed Brown
89d8606c27SBarry Smith  PetscCallA(VecSet(u, one, ierr))
90d8606c27SBarry Smith  PetscCallA(MatMult(A, u, b, ierr))
91c4762a1bSJed Brown
92c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
93c4762a1bSJed Brown!          Create the linear solver and set various options
94c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
95c4762a1bSJed Brown
96c4762a1bSJed Brown!  Create linear solver context
97c4762a1bSJed Brown
98d8606c27SBarry Smith  PetscCallA(KSPCreate(PETSC_COMM_WORLD, ksp, ierr))
99c4762a1bSJed Brown
100c4762a1bSJed Brown!  Set operators. Here the matrix that defines the linear system
1017addb90fSBarry Smith!  also serves as the matrix used to construct the preconditioner.
102c4762a1bSJed Brown
103d8606c27SBarry Smith  PetscCallA(KSPSetOperators(ksp, A, A, ierr))
104c4762a1bSJed Brown
105c4762a1bSJed Brown!  Set linear solver defaults for this problem (optional).
106c4762a1bSJed Brown!   - By extracting the KSP and PC contexts from the KSP context,
107d8606c27SBarry Smith!     we can then directly call any KSP and PC routines
108c4762a1bSJed Brown!     to set various options.
109c4762a1bSJed Brown!   - The following four statements are optional; all of these
110c4762a1bSJed Brown!     parameters could alternatively be specified at runtime via
111ccfd86f1SBarry Smith!     KSPSetFromOptions()
112c4762a1bSJed Brown
113d8606c27SBarry Smith  PetscCallA(KSPGetPC(ksp, pc, ierr))
114d8606c27SBarry Smith  PetscCallA(PCSetType(pc, PCFIELDSPLIT, ierr))
115c4762a1bSJed Brown  izero = 0
116c4762a1bSJed Brown  ione = 1
117d8606c27SBarry Smith  PetscCallA(ISCreateStride(PETSC_COMM_SELF, n, izero, ione, isin, ierr))
118dcb3e689SBarry Smith  PetscCallA(PCFieldSplitSetIS(pc, 'splitname', isin, ierr))
119dcb3e689SBarry Smith  PetscCallA(PCFieldSplitGetIS(pc, 'splitname', isout, ierr))
1204820e4eaSBarry Smith  PetscCheckA(isin == isout, PETSC_COMM_SELF, PETSC_ERR_PLIB, 'PCFieldSplitGetIS() failed')
121c4762a1bSJed Brown
122c4762a1bSJed Brown!  Set runtime options, e.g.,
123c4762a1bSJed Brown!      -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
124c4762a1bSJed Brown!  These options will override those specified above as long as
125c4762a1bSJed Brown!  KSPSetFromOptions() is called _after_ any other customization
126c4762a1bSJed Brown!  routines.
127c4762a1bSJed Brown
128d8606c27SBarry Smith  PetscCallA(KSPSetFromOptions(ksp, ierr))
129c4762a1bSJed Brown
130c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
131c4762a1bSJed Brown!                      Solve the linear system
132c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133e41f517fSBarry Smith  PetscCallA(PCSetUp(pc, ierr))
134e41f517fSBarry Smith  PetscCallA(PCFieldSplitGetSubKSP(pc, nksp, subksp, ierr))
1354820e4eaSBarry Smith  PetscCheckA(nksp == 2, PETSC_COMM_WORLD, PETSC_ERR_PLIB, 'Number of KSP should be two')
136e41f517fSBarry Smith  PetscCallA(KSPView(subksp(1), PETSC_VIEWER_STDOUT_WORLD, ierr))
137e41f517fSBarry Smith  PetscCallA(PCFieldSplitRestoreSubKSP(pc, nksp, subksp, ierr))
138c4762a1bSJed Brown
139d8606c27SBarry Smith  PetscCallA(KSPSolve(ksp, b, x, ierr))
140c4762a1bSJed Brown
141c4762a1bSJed Brown!  View solver info; we could instead use the option -ksp_view
142c4762a1bSJed Brown
143d8606c27SBarry Smith  PetscCallA(KSPView(ksp, PETSC_VIEWER_STDOUT_WORLD, ierr))
144c4762a1bSJed Brown
145c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
146c4762a1bSJed Brown!                      Check solution and clean up
147c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
148c4762a1bSJed Brown
149c4762a1bSJed Brown!  Check the error
150c4762a1bSJed Brown
151d8606c27SBarry Smith  PetscCallA(VecAXPY(x, none, u, ierr))
152d8606c27SBarry Smith  PetscCallA(VecNorm(x, NORM_2, norm, ierr))
153d8606c27SBarry Smith  PetscCallA(KSPGetIterationNumber(ksp, its, ierr))
1544820e4eaSBarry Smith  if (norm > 1.e-12) then
155c4762a1bSJed Brown    write (6, 100) norm, its
156c4762a1bSJed Brown  else
157c4762a1bSJed Brown    write (6, 200) its
158c4762a1bSJed Brown  end if
159c4762a1bSJed Brown100 format('Norm of error ', e11.4, ',  Iterations = ', i5)
160c4762a1bSJed Brown200 format('Norm of error < 1.e-12, Iterations = ', i5)
161c4762a1bSJed Brown
162c4762a1bSJed Brown!  Free work space.  All PETSc objects should be destroyed when they
163c4762a1bSJed Brown!  are no longer needed.
164c4762a1bSJed Brown
165d8606c27SBarry Smith  PetscCallA(ISDestroy(isin, ierr))
166d8606c27SBarry Smith  PetscCallA(VecDestroy(x, ierr))
167d8606c27SBarry Smith  PetscCallA(VecDestroy(u, ierr))
168d8606c27SBarry Smith  PetscCallA(VecDestroy(b, ierr))
169d8606c27SBarry Smith  PetscCallA(MatDestroy(A, ierr))
170d8606c27SBarry Smith  PetscCallA(KSPDestroy(ksp, ierr))
171d8606c27SBarry Smith  PetscCallA(PetscFinalize(ierr))
172c4762a1bSJed Brown
173c4762a1bSJed Brownend
174c4762a1bSJed Brown
175c4762a1bSJed Brown!/*TEST
176c4762a1bSJed Brown!
177c4762a1bSJed Brown!     test:
178c4762a1bSJed Brown!       args: -ksp_monitor
179c4762a1bSJed Brown!
180c4762a1bSJed Brown!TEST*/
181