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