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: {
  9:   MatScale(inA,alpha);
 10:   return 0;
 11: }

 13: extern PetscErrorCode MatScaleUserImpl(Mat,PetscScalar);

 15: static PetscErrorCode MatScaleUserImpl_MPIAIJ(Mat A,PetscScalar aa)
 16: {
 17:   Mat            AA,AB;

 19:   MatMPIAIJGetSeqAIJ(A,&AA,&AB,NULL);
 20:   MatScaleUserImpl(AA,aa);
 21:   MatScaleUserImpl(AB,aa);
 22:   return 0;
 23: }

 25: /* This routine registers MatScaleUserImpl_SeqAIJ() and
 26:    MatScaleUserImpl_MPIAIJ() as methods providing MatScaleUserImpl()
 27:    functionality for SeqAIJ and MPIAIJ matrix-types */
 28: PetscErrorCode RegisterMatScaleUserImpl(Mat mat)
 29: {
 30:   PetscMPIInt    size;

 32:   MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
 33:   if (size == 1) { /* SeqAIJ Matrix */
 34:     PetscObjectComposeFunction((PetscObject)mat,"MatScaleUserImpl_C",MatScaleUserImpl_SeqAIJ);
 35:   } else { /* MPIAIJ Matrix */
 36:     Mat AA,AB;
 37:     MatMPIAIJGetSeqAIJ(mat,&AA,&AB,NULL);
 38:     PetscObjectComposeFunction((PetscObject)mat,"MatScaleUserImpl_C",MatScaleUserImpl_MPIAIJ);
 39:     PetscObjectComposeFunction((PetscObject)AA,"MatScaleUserImpl_C",MatScaleUserImpl_SeqAIJ);
 40:     PetscObjectComposeFunction((PetscObject)AB,"MatScaleUserImpl_C",MatScaleUserImpl_SeqAIJ);
 41:   }
 42:   return 0;
 43: }

 45: /* this routines queries the already registered MatScaleUserImp_XXX
 46:    implementations for the given matrix, and calls the correct
 47:    routine. i.e if MatType is SeqAIJ, MatScaleUserImpl_SeqAIJ() gets
 48:    called, and if MatType is MPIAIJ, MatScaleUserImpl_MPIAIJ() gets
 49:    called */
 50: PetscErrorCode MatScaleUserImpl(Mat mat,PetscScalar a)
 51: {
 52:   PetscErrorCode (*f)(Mat,PetscScalar);

 54:   PetscObjectQueryFunction((PetscObject)mat,"MatScaleUserImpl_C",&f);
 55:   if (f) (*f)(mat,a);
 56:   return 0;
 57: }

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

 61: int main(int argc,char **args)
 62: {
 63:   Mat            mat;
 64:   PetscInt       i,j,m = 2,n,Ii,J;
 65:   PetscScalar    v,none = -1.0;
 66:   PetscMPIInt    rank,size;

 68:   PetscInitialize(&argc,&args,(char*)0,help);
 69:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
 70:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
 71:   n    = 2*size;

 73:   /* create the matrix */
 74:   MatCreate(PETSC_COMM_WORLD,&mat);
 75:   MatSetSizes(mat,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);
 76:   MatSetType(mat,MATAIJ);
 77:   MatSetUp(mat);

 79:   /* register user defined MatScaleUser() operation for both SeqAIJ
 80:      and MPIAIJ types */
 81:   RegisterMatScaleUserImpl(mat);

 83:   /* assemble the matrix */
 84:   for (i=0; i<m; i++) {
 85:     for (j=2*rank; j<2*rank+2; j++) {
 86:       v = -1.0;  Ii = j + n*i;
 87:       if (i>0)   {J = Ii - n; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
 88:       if (i<m-1) {J = Ii + n; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
 89:       if (j>0)   {J = Ii - 1; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
 90:       if (j<n-1) {J = Ii + 1; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
 91:       v = 4.0; MatSetValues(mat,1,&Ii,1,&Ii,&v,INSERT_VALUES);
 92:     }
 93:   }
 94:   MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);
 95:   MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);

 97:   /* check the matrix before and after scaling by -1.0 */
 98:   PetscPrintf(PETSC_COMM_WORLD,"Matrix _before_ MatScaleUserImpl() operation\n");
 99:   MatView(mat,PETSC_VIEWER_STDOUT_WORLD);
100:   MatScaleUserImpl(mat,none);
101:   PetscPrintf(PETSC_COMM_WORLD,"Matrix _after_ MatScaleUserImpl() operation\n");
102:   MatView(mat,PETSC_VIEWER_STDOUT_WORLD);

104:   MatDestroy(&mat);
105:   PetscFinalize();
106:   return 0;
107: }

109: /*TEST

111:    test:

113:    test:
114:       suffix: 2
115:       nsize: 2

117: TEST*/