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