Hello everyone,

I want to use PCApplyBAorAB symmetrically with a preconditioner from an ICC
factorization.
However, I don't understand why the result is not the same if I use a
natural or a RCM ordering during the factorization.
This problem does not occur if I use this routine with PC_LEFT or PC_RIGHT

I have put in attachment a code to illustrate the problem.
I compute a symmetric matix A in R^{n*n} and a full rank matrix B in R^{m*n}
I compute an ICC factorization of  the SPD matrix A+B^TB to precondition A.

Thank you!

Sylvain Mercier
      program main
      implicit none

! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
!                    include files
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
!
!     petscsys.h  - base PETSc routines    petscvec.h - vecteurs
!     petscmat.h  - matrices               petscpc.h  - preconditionneurs

#include <finclude/petscsys.h>
#include <finclude/petscvec.h>
#include <finclude/petscmat.h>
#include <finclude/petscpc.h>

      Vec   x,y,work
      Mat   A,K,C,Ct 
      PC    pc         
      PetscScalar  one,none
      PetscScalar  value(3)
      PetscInt  i,i1,i2,i3,intbid
      PetscInt  m,n,col(3)
      PetscMPIInt  rank
      PetscBool  flg
      PetscErrorCode  ierr
      MatFactorInfo  info


      call PetscInitialize(PETSC_NULL_CHARACTER,ierr)
      none = -1.D0
      one  = 1.D0
      n    = 10
      m    = 5
      i1 = 1
      i2 = 2
      i3 = 3
      call PetscOptionsGetInt(PETSC_NULL_CHARACTER,'-m',m,flg,ierr)
      call PetscOptionsGetInt(PETSC_NULL_CHARACTER,'-n',n,flg,ierr)
      call MPI_Comm_rank(PETSC_COMM_WORLD,rank,ierr)

! -------------------------------------------------------------------
!         Compute a symmetric matrix A (size n,n) and 
!         a full rank matrix C (size m,n)
! ------------------------------------------------------------------- 

      call MatCreate(PETSC_COMM_WORLD,A,ierr)
      call MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n,ierr)
      call MatSetFromOptions(A,ierr)
      value(1) = -1.0
      value(2) = 2.0
      value(3) = -1.0
      do 60 i=1,n-2
         col(1) = i-1
         col(2) = i
         col(3) = i+1
         call MatSetValues(A,i1,i,i3,col,value,INSERT_VALUES,ierr)
  60  continue
      i = n - 1
      col(1) = n - 2
      col(2) = n - 1
      call MatSetValues(A,i1,i,i2,col,value,INSERT_VALUES,ierr)
      i = 0
      col(1) = 0
      col(2) = 1
      value(1) = 2.0
      value(2) = -1.0
      call MatSetValues(A,i1,i,i2,col,value,INSERT_VALUES,ierr)
      call MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY,ierr)
      call MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY,ierr)

      call MatCreate(PETSC_COMM_WORLD,C,ierr)
      call MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,m,n,ierr)
      call MatSetFromOptions(C,ierr)
      call MatSetValue(C,0,0,one,INSERT_VALUES,ierr)
      call MatSetValue(C,0,5,one,INSERT_VALUES,ierr)
      call MatSetValue(C,1,1,one,INSERT_VALUES,ierr)
      call MatSetValue(C,2,2,one,INSERT_VALUES,ierr)
      call MatSetValue(C,3,3,one,INSERT_VALUES,ierr)
      call MatSetValue(C,3,4,none,INSERT_VALUES,ierr)
      call MatSetValue(C,4,5,one,INSERT_VALUES,ierr)
      call MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY,ierr)
      call MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY,ierr)
!      call MatView(A,PETSC_VIEWER_STDOUT_WORLD,ierr)
!      call MatView(C,PETSC_VIEWER_STDOUT_WORLD,ierr)

! -------------------------------------------------------------------
!         Compute K=A+C^TC (symmetric positive definite) 
! ------------------------------------------------------------------- 

      call MatTranspose(C,MAT_INITIAL_MATRIX,Ct,ierr)
      call MatMatMult(Ct,C,MAT_INITIAL_MATRIX,1.D0,K,ierr)
      call MatAXPY(K,1.D0,A,DIFFERENT_NONZERO_PATTERN,ierr) 
!      call MatView(K,PETSC_VIEWER_STDOUT_WORLD,ierr)

! -------------------------------------------------------------------
!         Create the PC object to precondition A with an ICC of K 
!         and compute an example of PCApplyBAorAB (symmetric)
! ------------------------------------------------------------------- 

      call VecCreateMPI(PETSC_COMM_WORLD,PETSC_DECIDE,n,x,ierr)
      call VecDuplicate(x,y,ierr)
      call VecDuplicate(y,work,ierr)
      call VecSet(x,one,ierr)

!  Using MATORDERINGNATURAL
      call PCCreate(PETSC_COMM_WORLD,pc,ierr)
      call PCSetOperators(pc,A,K,SAME_NONZERO_PATTERN,ierr)
      call PCSetType(pc,PCICC,ierr)
      call PCFactorSetLevels(pc,5,ierr)
      call PCFactorSetMatOrderingType(pc,MATORDERINGNATURAL,ierr)

      call PCApplyBAorAB(pc,PC_SYMMETRIC,x,y,work,ierr)
      write(*,*)'Natural Ordering:'
      call VecView(y,PETSC_VIEWER_STDOUT_WORLD,ierr)    

!  Using MATORDERING RCM
      call PCCreate(PETSC_COMM_WORLD,pc,ierr)
      call PCSetOperators(pc,A,K,SAME_NONZERO_PATTERN,ierr)
      call PCSetType(pc,PCICC,ierr)
      call PCFactorSetLevels(pc,5,ierr)
      call PCFactorSetMatOrderingType(pc,MATORDERINGRCM,ierr)

      call PCApplyBAorAB(pc,PC_SYMMETRIC,x,y,work,ierr)
      write(*,*)'RCM Ordering:'
      call VecView(y,PETSC_VIEWER_STDOUT_WORLD,ierr)    

!  Free work space.  All PETSc objects should be destroyed when they
!  are no longer needed.

      call VecDestroy(x,ierr)
      call VecDestroy(y,ierr)
      call VecDestroy(work,ierr)
      call MatDestroy(A,ierr)
      call MatDestroy(C,ierr)
      call MatDestroy(Ct,ierr)
      call MatDestroy(K,ierr)

!  Always call PetscFinalize() before exiting a program. 

      call PetscFinalize(ierr)
      end







Reply via email to