Actual source code: ex8.c


  2: static char help[] = "Shows how to add a new MatOperation to AIJ MatType\n\n";

  4: #include <petscmat.h>
  5: #include <petscblaslapack.h>

  7: static PetscErrorCode MatScaleUserImpl_SeqAIJ(Mat inA,PetscScalar alpha)
  8: {

 12:   MatScale(inA,alpha);
 13:   return(0);
 14: }

 16: extern PetscErrorCode MatScaleUserImpl(Mat,PetscScalar);

 18: static PetscErrorCode MatScaleUserImpl_MPIAIJ(Mat A,PetscScalar aa)
 19: {
 21:   Mat            AA,AB;

 24:   MatMPIAIJGetSeqAIJ(A,&AA,&AB,NULL);
 25:   MatScaleUserImpl(AA,aa);
 26:   MatScaleUserImpl(AB,aa);
 27:   return(0);
 28: }

 30: /* This routine registers MatScaleUserImpl_SeqAIJ() and
 31:    MatScaleUserImpl_MPIAIJ() as methods providing MatScaleUserImpl()
 32:    functionality for SeqAIJ and MPIAIJ matrix-types */
 33: PetscErrorCode RegisterMatScaleUserImpl(Mat mat)
 34: {
 36:   PetscMPIInt    size;

 39:   MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
 40:   if (size == 1) { /* SeqAIJ Matrix */
 41:     PetscObjectComposeFunction((PetscObject)mat,"MatScaleUserImpl_C",MatScaleUserImpl_SeqAIJ);
 42:   } else { /* MPIAIJ Matrix */
 43:     Mat AA,AB;
 44:     MatMPIAIJGetSeqAIJ(mat,&AA,&AB,NULL);
 45:     PetscObjectComposeFunction((PetscObject)mat,"MatScaleUserImpl_C",MatScaleUserImpl_MPIAIJ);
 46:     PetscObjectComposeFunction((PetscObject)AA,"MatScaleUserImpl_C",MatScaleUserImpl_SeqAIJ);
 47:     PetscObjectComposeFunction((PetscObject)AB,"MatScaleUserImpl_C",MatScaleUserImpl_SeqAIJ);
 48:   }
 49:   return(0);
 50: }

 52: /* this routines queries the already registered MatScaleUserImp_XXX
 53:    implementations for the given matrix, and calls the correct
 54:    routine. i.e if MatType is SeqAIJ, MatScaleUserImpl_SeqAIJ() gets
 55:    called, and if MatType is MPIAIJ, MatScaleUserImpl_MPIAIJ() gets
 56:    called */
 57: PetscErrorCode MatScaleUserImpl(Mat mat,PetscScalar a)
 58: {
 59:   PetscErrorCode ierr,(*f)(Mat,PetscScalar);

 62:   PetscObjectQueryFunction((PetscObject)mat,"MatScaleUserImpl_C",&f);
 63:   if (f) {
 64:     (*f)(mat,a);
 65:   }
 66:   return(0);
 67: }

 69: /* Main user code that uses MatScaleUserImpl() */

 71: int main(int argc,char **args)
 72: {
 73:   Mat            mat;
 74:   PetscInt       i,j,m = 2,n,Ii,J;
 76:   PetscScalar    v,none = -1.0;
 77:   PetscMPIInt    rank,size;

 79:   PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
 80:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
 81:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
 82:   n    = 2*size;

 84:   /* create the matrix */
 85:   MatCreate(PETSC_COMM_WORLD,&mat);
 86:   MatSetSizes(mat,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);
 87:   MatSetType(mat,MATAIJ);
 88:   MatSetUp(mat);

 90:   /* register user defined MatScaleUser() operation for both SeqAIJ
 91:      and MPIAIJ types */
 92:   RegisterMatScaleUserImpl(mat);

 94:   /* assemble the matrix */
 95:   for (i=0; i<m; i++) {
 96:     for (j=2*rank; j<2*rank+2; j++) {
 97:       v = -1.0;  Ii = j + n*i;
 98:       if (i>0)   {J = Ii - n; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
 99:       if (i<m-1) {J = Ii + n; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
100:       if (j>0)   {J = Ii - 1; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
101:       if (j<n-1) {J = Ii + 1; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
102:       v = 4.0; MatSetValues(mat,1,&Ii,1,&Ii,&v,INSERT_VALUES);
103:     }
104:   }
105:   MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);
106:   MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);

108:   /* check the matrix before and after scaling by -1.0 */
109:   PetscPrintf(PETSC_COMM_WORLD,"Matrix _before_ MatScaleUserImpl() operation\n");
110:   MatView(mat,PETSC_VIEWER_STDOUT_WORLD);
111:   MatScaleUserImpl(mat,none);
112:   PetscPrintf(PETSC_COMM_WORLD,"Matrix _after_ MatScaleUserImpl() operation\n");
113:   MatView(mat,PETSC_VIEWER_STDOUT_WORLD);

115:   MatDestroy(&mat);
116:   PetscFinalize();
117:   return ierr;
118: }

120: /*TEST

122:    test:

124:    test:
125:       suffix: 2
126:       nsize: 2

128: TEST*/