xref: /petsc/src/ksp/pc/tests/ex9f.F90 (revision e41f517f4d18e1c8d622486babf146494d335f64)
1c4762a1bSJed Brown!
2a5b23f4aSJose E. Roman!   Description: Tests PCFieldSplitGetIS and PCFieldSplitSetIS from Fortran.
3c4762a1bSJed Brown!
4c4762a1bSJed Brown      program main
5c4762a1bSJed Brown#include <petsc/finclude/petscksp.h>
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
16*e41f517fSBarry Smith      PetscInt ione,izero,nksp
17c4762a1bSJed Brown      PetscBool  flg
18c4762a1bSJed Brown      PetscMPIInt size
19c4762a1bSJed Brown      PetscScalar      none,one,value(3)
20*e41f517fSBarry Smith      KSP, pointer :: subksp(:)
21*e41f517fSBarry 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))
30dcb3e689SBarry Smith      PetscCheckA(size .eq. 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
59c4762a1bSJed Brown      do 50 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))
64c4762a1bSJed Brown  50  continue
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))
120dcb3e689SBarry Smith      PetscCheckA(isin .eq. 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! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133*e41f517fSBarry Smith      PetscCallA(PCSetUp(pc,ierr))
134*e41f517fSBarry Smith      PetscCallA(PCFieldSplitGetSubKSP(pc,nksp,subksp,ierr))
135*e41f517fSBarry Smith      PetscCheckA(nksp .eq. 2,PETSC_COMM_WORLD,PETSC_ERR_PLIB,'Number of KSP should be two')
136*e41f517fSBarry Smith      PetscCallA(KSPView(subksp(1),PETSC_VIEWER_STDOUT_WORLD,ierr))
137*e41f517fSBarry 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))
154c4762a1bSJed Brown      if (norm .gt. 1.e-12) then
155c4762a1bSJed Brown        write(6,100) norm,its
156c4762a1bSJed Brown      else
157c4762a1bSJed Brown        write(6,200) its
158c4762a1bSJed Brown      endif
159c4762a1bSJed Brown 100  format('Norm of error ',e11.4,',  Iterations = ',i5)
160c4762a1bSJed Brown 200  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 Brown      end
174c4762a1bSJed Brown
175c4762a1bSJed Brown!/*TEST
176c4762a1bSJed Brown!
177c4762a1bSJed Brown!     test:
178c4762a1bSJed Brown!       args: -ksp_monitor
179c4762a1bSJed Brown!
180c4762a1bSJed Brown!TEST*/
181