program test_pc_apply_transpose

  IMPLICIT NONE

#include "finclude/petsc.h"

  ! Petsc variables
  PetscErrorCode  ierr
  PetscViewer     pviewer
  Mat     H
  Vec     vin, vout
  PC      PPC

  ! --------------------------------------------

  call PetscInitialize(PETSC_NULL_CHARACTER,ierr); CHKERRQ(ierr)
 
  call PetscPrintf(PETSC_COMM_WORLD,"\nProgram started\n",ierr); CHKERRQ(ierr);

  call PetscPrintf(PETSC_COMM_WORLD,"Reading input matrix H.petsc...\n",ierr); CHKERRQ(ierr)
  call PetscViewerBinaryOpen(PETSC_COMM_WORLD,"H.petsc",FILE_MODE_READ,pviewer,ierr); CHKERRQ(ierr)
  call MatCreate(PETSC_COMM_WORLD,H,ierr); CHKERRQ(ierr)
  call MatLoad(H,pviewer,ierr); CHKERRQ(ierr)
  call PetscViewerDestroy(pviewer,ierr); CHKERRQ(ierr)

  call PetscPrintf(PETSC_COMM_WORLD,"Reading input vector vin.petsc...\n",ierr); CHKERRQ(ierr)
  call PetscViewerBinaryOpen(PETSC_COMM_WORLD,"vin.petsc",FILE_MODE_READ,pviewer,ierr); CHKERRQ(ierr)
  call VecCreate(PETSC_COMM_WORLD,vin,ierr); CHKERRQ(ierr)
  call VecLoad(vin,pviewer,ierr); CHKERRQ(ierr)
  call PetscViewerDestroy(pviewer,ierr); CHKERRQ(ierr)

  call PetscPrintf(PETSC_COMM_WORLD,"Setting up the PC object...\n",ierr); CHKERRQ(ierr)
  call PCCreate(PETSC_COMM_WORLD,PPC,ierr); CHKERRQ(ierr)
!   call PCSetOperators(PPC,H,H,SAME_PRECONDITIONER,ierr); CHKERRQ(ierr) ! PETSc-3.4
  call PCSetOperators(PPC,H,H,ierr); CHKERRQ(ierr)
!  call PCSetOptionsPrefix(PPC,'ppc_mt_',ierr); CHKERRQ(ierr)
  call PCSetFromOptions(PPC,ierr); CHKERRQ(ierr)
  call PCFactorSetShiftType(PPC,MAT_SHIFT_NONZERO,ierr); CHKERRQ(ierr)
  call PCSetUp(PPC,ierr); CHKERRQ(ierr)
  call PCView(PPC,PETSC_VIEWER_STDOUT_WORLD,ierr); CHKERRQ(ierr)

  call PetscPrintf(PETSC_COMM_WORLD,"Creating the output vector...\n",ierr); CHKERRQ(ierr)
  call VecDuplicate(vin,vout,ierr); CHKERRQ(ierr)

  call PetscPrintf(PETSC_COMM_WORLD,"Applying the pre-conditioner transpose...\n",ierr); CHKERRQ(ierr)
  call PCApplyTranspose(PPC,vin,vout,ierr); CHKERRQ(ierr)
  
  call PetscPrintf(PETSC_COMM_WORLD,"Writing the resulting vector to file vout.petsc...\n",ierr); CHKERRQ(ierr)
  call PetscViewerBinaryOpen(PETSC_COMM_WORLD,"vout.petsc",FILE_MODE_WRITE,pviewer,ierr); CHKERRQ(ierr)  
  call VecView(vout,pviewer,ierr); CHKERRQ(ierr)
  call PetscViewerDestroy(pviewer,ierr); CHKERRQ(ierr)

  call PetscPrintf(PETSC_COMM_WORLD,"Terminating the program...\n\n",ierr); CHKERRQ(ierr)
  call PCDestroy(PPC,ierr); CHKERRQ(ierr)
  call MatDestroy(H,ierr); CHKERRQ(ierr)
  call VecDestroy(vin,ierr); CHKERRQ(ierr)
  call VecDestroy(vout,ierr); CHKERRQ(ierr)
  call PetscFinalize(ierr); CHKERRQ(ierr)

end program test_pc_apply_transpose
